【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约

Solidity 介绍 智能合约(Smart contract )是一种旨在以信息化方式传播验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于1995年由Nick Szabo首次提出。智能合约的目的是提供优于传统合约的安全方法,并减少与合约相关的其他交易成本。简单地说,智能合约可以理解为一个自执行的协议。智能合约可以自动处理协议的履行、管理、以及支付。 阅读详情

在这里插入图片描述

有好几种语言可以用于编写以太坊智能合约,不过Solidity是最热门的语言。在本章中,我们将首先学习Solidity编程语言。然后创建一个DApp,用于证明在特定时间的存在、真实性和所有权,即证明一个文件在一个特定时间属于一个特定所有者。

要点:

  • Solidity源文件的布局
  • 理解Solidity的数据类型
  • 合约的特殊变量和函数
  • 控制结构
  • 合约的结构和功能
  • 编译和部署合约

Solidity源文件

Solidity源文件使用的扩展名为.sol。这里面我们使用的是0.4.2版本。

智能合约的结构

合约就像一个类(class),其中包含:

  • 状态变量(state variable)
  • 函数(function)
  • 函数修改器(function modifier)
  • 事件(event)
  • 结构(structure)
  • 枚举(enum)

同时,合约还支持继承与多态。

示例:

contract Sample
{
	//状态变量
	uint256 data;
	address owner;
	
	//定义事件
	event logData(uint256 dataToLog);
	//函数修改器
	modifier onlyOwner() {
		if(msg.sender!=owner) throw;
		
	}
	//构造器,名字与合约名一致
	function Sample(uint256 initData,address initOwner) {
		data = initData;
		owner = initOwner;
	}
	//函数
	function getData() returns (uint256 returnedData) {
	return data;	
	}
	function setData() returns (uint256 newData) onlyOwner {
		logData(newData);
		data = newData;
	}
	
}

代码注释:

  • contract 关键字:用于声明一个合约

  • data和owner:是两个状态变量。data包含一些数据,owner包含所有者的以太坊钱包地址,即部署合约者的以太坊地址

  • event logData 定义事件logData,用于通知客户端:一旦data发生变化,将触发这个事件。所有事件都保存在区块链中。

  • 函数修改器:onlyOwner。修改器用于在执行一个函数之前自动检测文件。这里的修改器用于检测合约所有者是否在调用函数。如果没有,则会抛出异常。

  • 合约函数构造器constructor:在部署合约时,构造器用于初始化状态变量。

  • function,getData()用于得到data状态变量的值,setData()用于改变data的值。

数据位置(较难理解)

通常,变量会存储在内存中。但是,在Solidity中,会根据不同的情况,变量可能会不存储在内存和文件系统中。

通常,在Solidity中,数据有一个默认位置。通常,存储有一个storage位置和一个memory位置,即本地存储与内存存储。

函数参数,包括其返还参数,默认用memory,本地变量默认用storage,例如状态变量,其数据位置强制使用storage。

注意:

  • 不能把memory中存储的复杂类型分配给storage;

###什么是不同的数据类型

首先明白3点;

  • Solidity是一种静态类型语言,变量存储的数据类型需要预先定义。
  • 所有变量默认值都是0。
  • 在Solidity中,变量是有函数作用范围的,也就是说,在函数中任何地方声明的变量将对整个函数存在适用范围。

那么Solidity提供了哪些数据类型——》

基本类型

除了数组类型、字符串类型、结构类型、枚举类型和map类型外,
其他类型均称为基本类型。

  • 无符号型:例如uint8,uint16,uint24,…,uint256分别用于存储无符号的8位,16
    位,24位,…,256位整数
  • 有符号型:例如,int8,int16,…,int256分别用于存储8位,16位,24位,…,256位整数
  • address类型:用于存储以太坊地址,用16进制表示。address类型有两个属性:balance和send。balance用于检测地址余额,send用于向地址发送以太币。send方法拿出需要转账那
    些数量的wei,并根据转账是否成功返回true或者false。

注意:

  • uint和int是uint256和int256的别名。

  • 如果一个数字超过256位,则使用256位数据类型存储该数字的近似值。

  • 数组:Solidity支持generic和byte两种数组类型。

数组有length属性,用于发现数组的长度。

注意:不可以在内存中改变数组大小,也不可以改变非动态数组大小。

字符串类型

有两种方法创建字符串:使用bytes和string。
bytes用于创建原始字符串,而string用于创建UTF-8字符串

示例:

contract sample {
    string myString = "";// string
    bytes myRawString;

    function sample(string initString,bytes rawStringInit) {
        myString = initString;

        string storage myString2 = myString;
        string memory myString3 = "ABCDE";
        myString3 = "imaginecode";
        myRawString = rawStringInit;
        myRawString.length++;
    }
}

结构类型struct

示例

contract sample {
	struct myStruct {
		bool myBool;
		string myString;
	}
	myStruct s1;
	myStruct s2 = myStruct{true,""}; 
	
	function sample(bool initBool,string initString){
		s1 = myStruct(initBool,initString);
		
		myStruct memory s3 = myStruct(initBool,initString);
	}
}

注意:函数参数不可以是结构类型,且函数不可以返回结构类型。

枚举类型 enum

示例

contract sample {
    enum OS {OSX, Linux,Unix,windows }

    OS choice;

    function sample(OS chosen) {
        choice = chosen;
    }
    function setLinux() {
        choice = OS.Linux;
    }
    function getChoice return (OS chosenOS) {
        return choice;
    }
}

mapping 类型

  • mapping类型只可以存在于storage中,不存在于memory中,因此它们是作为状态变量声明的。

  • mapping类型包含key/value对,不是实际存储key,而是存储key的keccak256哈希,用于查询value。

  • mapping不可以被分配给另一个mapping。

constract sample {
	mapping (int => string) myMap;
	function sample(){
		myMap[key] = value;
		mapping (int => string) myMap2 = myMap;
	}
}

注意:如果想访问mapping中不存在的key,返回的value为0。

delete 操作符

可用于操作任何类型的变量。

  • 对动态数组使用delete操作符,则删除所有元素,其长度变为0。

  • 对静态数组使用delete操作符,则重置所有索引

  • 对map类型使用delete操作符,什么都不会发生,但是,对map类型的一个键使用delete操作符,则会删除与该键相关的值

示例

contract sample {
    struct Struct {
        mapping (int => int) myMap;
        int myNumber;
    }
    int[] myArray;
    Struct myStruct;

    function sample(int key,int value,int number,int[] array) {
        myStruct = Struct(number);

        myStruct = Struct(number);
        myStruct.myMap[key] = value;//对某个键赋值
        myArray = array;
    }
    function reset() {
        delete myArray;//myArray数组长度为0
        delete myStruct;//myNumber为0,myMap不变
    }
    function deleteKey(int key) {
    		delete myStruct.myMap[key];//删除myMap中的某个键的值
    }
}

基本类型之间的转换

  • 隐式转换:常用。通常来说,如果没有语义信息丢失,值和类型之间可以进行隐式转换:uint8可转换为uint16,int128可转换为int256,但是int8不可转换为uint256(因为uint256不能存储,例如-1)
  • Solidity也支持显式转换,如果编译器不允许在两种数据类型之间隐式转换,则可以进行显式转换。建议尽量避免显式转换,因为可能返回难以预料的结果。

示例:

uint32 a = 0x12345678;
uint16 b = uint16(a); // b = 0x5678,将uint32类型显式转换为uint16,也就是说,把较大类型转换为较小类型,因此高位被截掉了

var

使用关键字var声明的变量,其变量类型根据分配给它的第一个值来动态确定。一旦分配了值,类型就固定了,所以如果给它指定另一个类型,将引起类型转换。

int256 x= 12;
var y = x;//此时y的类型是int256

uint256 z = 9;
y = z;//此时,报出异常,因为uint256不能转换为int256类型

但要注意的是:

  • 在定义数组array和map时不能使用var。var也不能用于定义函数参数和状态变量

控制结构

  • if-else
  • while
  • for
  • break\continue
  • return
  • ?:
  • 等等
//结构上和其他语法没有什么差异
contract sample {
	int a = 12;
	int[] b;
	
	function sample() {
		if(a == 12) {}
		else if(a==34){}
		else {}
		var temp = 10;
		while(temp<20)
		{
			if(temp==17){break;}
			else {continue;}
		}
		temp++;
	}
	for(var m=0;m<b.length;m++){
	
	}
}

用new 操作符创建合约

一个合约可以使用new关键字来创建一个新合约。

例如:

contract sample1 {
	int a;
	function assign(int b){
		a = b;
	}
}

contract sample2 {
	function sample2(){
		sample1 s = new sample1(); //注意写法
		s.assign(12);
	}
}

异常

异常的抛出分为自动和手动。
若你想手动抛出异常,可以使用throw手动抛出。
注意,异常抛出后,会撤销对状态和余额的所有改变。

contract sample {
	function myFunction () {
		throw;
	}
}

函数调用

  • 内部函数调用:一个函数在同一个合约中调用另一个函数
  • 外部函数调用:一个函数调用另一个合约的函数。

外部函数调用–this关键字

合约sample1

contract sample1 {
	int a;
	function sample1(int b) payable {
		a = b;
	}
	function assign(int c){
		a = c;
	}
	function makePayment(int d) payable {
		a = d;
	}
}

合约sample2

contract sample2 {
	function hello() {}
	function sample2(address addressOfContract){
		sample1 s = (new sample1).value(12)(23);
		s.makePayment(22);
		s.makePayment.value(45)(12);
		s.makePayment.value(4).gas(900)(12);
		this.hello(); //利用this调用外部合约函数
		sample1 s2 = sample1(addressOfContract);
		s2.makePayment(112);
	}
}

注意:使用this关键字进行的调用称为外部调用。在函数中,this关键字代表当前合约实例

合约功能——深入理解合约

可见性

可见性定义了谁可以看到它,函数和状态变量有四种可见性:external、public、internal和private

  • 函数可见性,默认为 public

  • 状态变量可见性,默认为 internal

  • external:外部函数只能由其他合约调用,或者通过交易调用——this.f()

  • public:公共函数和状态变量可以用所有可行办法访问

  • internal:内部函数和状态变量只可以内部访问,即从当前合约内和继承它的合约访问。不可以使用this访问它

  • private:私有函数和状态变量类似于内部函数,但是继承合约不可以访问它们

示例

contract sample1 {
	int public b = 78;
	int internal c = 90;
	
	function sample1() {
		this.a();//外部访问
		b = 21;//内部访问
		
	}
	function a() external {}
}

contract sample2 {
	int internal d = 9;
	int private e = 90;
}
//sample3 继承 sample2
contract sample3 is sample2 {
	sample1 s;
	function sample3() {
		s = new sample1();
		s.a();//外部访问
	}
}

函数修改器(较难理解)

先看一个修改器的例子:

contract sample {
    int a = 90;
    modifier myModifier1(int b) {
        int c = b;
        _;
        c = a;
        a = 1;
    }
    modifier myModifier2 {
        int c = a;
        _;
       
    }
    modifier myModifier3 {
        a = 96;
        return;
        _;
        a = 99;
    }
    modifier myModifier4 {
        int c = a;
        _;
    }
    function myFunction() myModifier1(a) myModifier2 myModifier3 returns (int d) {
        a = 2;
        return a;
    }

}

注:

  • 在修改器中,无论下一个修改器体或者函数体二者哪个先到达,都会被插入到“_;”出现的地方。

回退函数

即一个合约中唯一一个未命名函数。

  • 不能有实参
  • 不能有返回值
  • 如果其他函数都不能匹配给定的函数标识符,那么就执行回退函数
  • 如果你想让你的合约接收以太币,就必须实现回退函数
contract sample {
	function() payable {
	
	}
}

继承

即使一个合约继承自其他多个合约,在区块链上也只会创建一个合约。
父合约的代码总是会被复制到最终合约里。

  • 关键字 is

示例

contract sample1 {
	function a(){}
	function b() {}
}
//合约2继承自合约1
contract sample2 is sample1{
	function b() {}
}
contract sample3{
	function sample3(int b){
	}
}
//合约4继承自合约1与合约2
contract sample4 is sample1,sample2 {
	function a(){}
	function c() {
		a();
		//执行合约1中的a方法
		sample1.a();
		//执行合约2中的b方法
		b();
	}
}
关键字super
  • 用于引用最终继承链中的下一个合约
    示例
contract sample1{
}
contract sample2{
}
contract sample3 is sample2{
}
contract sample4 is sample2{
}
contract sample5 is sample4{
	function myFunc(){}
}
contract sample6 is sample1,sample2,sample3,sample4,sample5 {
	function myFunc() {
	//执行sample5中的myFunc方法
		super.myFunc();
	}
}
抽象合约
  • 仅包含函数原型而不包含函数实现的合约
  • 抽象合约不能被编译
  • 如果一个合约继承自抽象合约且不重写,那么它自己也是抽象合约

示例

contract sample1{
	function a() returns (int b);
}
contract sample2{
	function myFunc(){
		sample1 s = sample();
		s.a();
	}
}

库

库的目的是在一个特定地址中只部署一次,其其代码可供复用。

示例-使用solidity的math库:

library math
{
	function addInt(int a,int b) return (int c){
		return a+b;
	}
}
contract sample {
	function data() returns (int d){
		return math.addInt(1,2);//调用math库中的addInt方法
	}
}

使用场景

  • 如果有许多合约,这些合约有一些共同的代码,那么可以把它们共同的代码部署成一个库。这么做的好处是这样能节省gas。因为gas的大小依赖于合约的规模。

返回多个值

示例:

contract sample{
	function a() returns (int a,string c){
			return (1,"m");
	}
	function b(){
		int A;
		string memory B;
		
		(A,B) = a();// A =1,B = "m"
		(A,)  = a();// A =1
		(,B) = a(); //B = "m"
	}
}

全局变量

  • 特殊变量
  • 特殊函数
1、区块和交易属性
  • block.blockhash(uint blockNumber) returns (bytes32) //区块哈希值
  • block.coinbase(address) //当前区块矿工的地址
  • block.difficulty(uint) //当前区块的难度值
  • block.gaslimit(uint) //当前区块的gas上限,定义了整个区块中的所有交易最多能消耗多少gas
  • block.number(uint) //当前区块的序号
  • block.timestamp(uint) //当前区块的时间戳
  • msg.gas(uint) //当前剩余的gas
  • msg.sender(address) //当前调用发起人的地址
  • msg.sig(bytes4) //调用数据的前四个字节
  • msg.value(uint) //这个消息所附带的货币量,单位为wei
  • now(uint) //当前区块的时间戳,等同于block.timestamp
  • tx.gasprice(uint) //交易的gas价格
  • tx.origin(address) //交易的发起人
2、地址类型相关
  • .balance(uint256) //地址余额,单位为wei
  • .send(uint256 amount) returns(bool) //发送指定数量的wei到地址
3、合约相关
  • this //当前合约
  • selfdestruct(address recipient) //销毁当前合约,把其中的资金发送到指定地址

以太币单位

一个数字可以用wei、finney、szabo、Ether等单位转换为不同面值的以太币。默认使用wei为单位。

存在、真实性和所有权合约的证明

下面我们要实现一个“证明文件所有权”的合约。

分以下几步来进行:

  • 1、成对存储文件的哈希和文件所有者的名字,用以实现所有权证明(PoO)
  • 2、成对存储文件的哈希和区块的时间戳,用以实现文件在某个特定时间存在的证明(PoE)
  • 3、存储哈希自身,用以证明文件的真实性。如果文件被修改,其哈希也会被改变。更改过的文件的哈希会使得合约无法发现文件,从而证明文件被修改过。

代码如下:

contract Proof{
	struct FileDetails {
		uint timestamp;
		string owner;
	}
	mapping (string => FileDetails) files;
	
	event logFileAddedStatus(bool status,uint timestamp,string owner,string fileHash);
	
	//存储文件所有者
	function set(string owner,string fileHash){
		if(files[fileHash].timestamp==0){
			files[fileHash] = FileDetails(block.timestamp,owner);
			//触发一个事件以至于前端应用知道文件的存在
			logFileAddedStatus(true,block.timestamp,owner,fileHash);
		}else {
		//告诉前端文件存在,但是不能存储
			logFileAddedStatus(false,block.timestamp,owner,fileHash);
		}
	}
	//获取文件信息
	function get(string fileHash) returns (uint timestamp,string owner){
		return (files[fileHash].timestamp,files[fileHash].owner);
	}
}

编译和部署合约

这里,我们使用solcjs和Browser Solidity ,其中solcjs允许在node.js中以编程方式编译Solidity,而Browser Solidity是一个适用于小型合约的IDE。

至此,我们将Solidity语言进行了基本的讲解,下一节中我们将介绍如何使用web3.js开发DApp前端。

solidity编程 简介简介Solidity是⼀种⽤于编写以太坊虚拟机(EVM)智能合约的编程语⾔。我认为掌握Solidity是参与链上项⽬的必备技能:区块链项⽬⼤部分是开源的,如果你能读懂代码,就可以规避很多亏钱项⽬。Solidity具有两个特点:1.基于对象:学会Solidity之后,可以助你在区块链领域找到好⼯作,挣钱找对象。2.⾼级:不会Solidity,在币圈会显得很low进去之后会有四个选项,选择第三个第⼀个程序文件后缀名为.sol第1。 阅读详情

相关推荐

Solidity编程语言

Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在以太坊虚拟机(EVM)上运行。 Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。 Solidity 编程的推荐方式是使用 Remix。Remix是一个基于 Web 浏览器的 IDE,它可以 让你编写 Solidity 智能合约,然后部署并运行该智能合约。Solidity 源 码文件通常以 .sol 作为扩展名。 以太坊底

m0_49978528的博客 6871

Solidity基础(详细易懂!!!)

不拘泥于死板的语法基础知识,从实用性出发,通过多个实用性的智能合约的编写,由浅入深的介绍了有关于Solidity相关基础知识的用法,同时也是博主的区块链学习系列之一,感谢大家阅读!

m0_73094011的博客 2万+

手把手教你一步步开发第一个Dapp(使用solidity语言实现投票合约)——Remix版本

第一个Dapp开发(使用solidity语言实现投票合约)——Remix版本 Remix使用教程 MetaMask使用教程 Dapp开发技术 Web3.js

自我总结,分享所有,快乐每一天 1万+

Solidity——速通学习

这一讲,我们介绍了什么是函数选择器selector),它和msg.data函数签名的关系,以及如何使用它调用目标函数。在这一讲,我们介绍了如何在Solidity使用try-catch只能用于外部合约调用和合约创建。如果try执行成功,返回变量必须声明,并且与返回的变量类型相同。

qq_46573670的博客 2626

一起学:以太坊智能合约开发

课程介绍 无论在科技圈还是金融圈,“区块链”俨然成了最热的词汇。2016年,区块链写入了国家的十三五规划中;2017年,央行基于区块链技术的数字票据交易平台测试成功;同年,工信部发布了首个区块链参考架构标准。
经过2017年如火如荼的投资盛宴,区块链开始逐渐走向应用落地,业内都在积极探索使用场景。如金融领域的资产贸易、支付系统、金融服务,其他领域的电子商务、社交通讯、游戏娱乐等等。同时,BAT、迅...

GitChat 1万+

探秘区块链开发:智能合约在 DApp 中的地位及与传统开发差异

在区块链开发中,多数时候讨论的是 DApp 开发,而智能合约则是 DApp 的重要组成部分。为了方便普通开发者理解,我这里以传统 App 为切入点,对智能合约进行讲解,将其类比为前端开发者调用的 API 或后端开发者开发的入库程序。同时强调智能合约开发与传统 API 开发存在不同,主要体现在以下方面:一是开发语言不同,如以太坊用 Solidity,Hyperledger Fabric 用 Go

银二码的代码博客 1418

区块链智能合约编程语言 Solidity

上文介绍了区块链生态发展,我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。Solidity 是以太坊开发人员使用的编程语言,用来编写智能合约,运行在以太坊虚拟机(EVM)上。

二蛋的博客 4954

从后端到智能合约开发:需要多久

根据个人情况设计你的学习规划,每天坚持学习2-4小时,在6个月内掌握从智能合约开发所需的技能,并不是难事。我是田大正,一个7年全栈经验,目前已经全面转型到web3,如果你在关注区块链,web3市场,正在规划自己的转型路径,欢迎跟我私信交流,愿意与你分享我的转型经验。学习资源:React.js或Vue.js、Web3.js或Ethers.js教程。学习资源:Solidity文档、高级课程、GitHub上开源智能合约代码。学习资源:Mocha、Chai、Truffle、Hardhat教程。

Qztiandazheng的博客 2132

DApp开发

了解DApp开发过程什么是DApp?二级目录三级目录 什么是DApp? DApp即分布式应用或去中心化应用,DApp于区块链,就好比App于iOS和Android。 一个真正的DApp应用,需要同时满足以下几个条件: 1、应用必须完全开源、自治,且没有一个实体控制该应用超过51%的Token。该应用必须能够根据用户的反馈及技术要求进行升级,且应用升级必须由大部分用户达成共识之后方可进行; 2、应用的数据必须加密后存储在公开的区块链上; 3、应用必须拥有Token机制,矿工或应用维护节点需得到代币奖励; 4

@ 1万+

solidity智能合约

在这种情况下,攻击方的胜利次数和等级都会增加,被攻击方的失败次数会增加,并调用feedAndMultiply函数,以将攻击方的DNA和被攻击方的DNA混合在一起,创建一个新的僵尸。feedOnKitty 函数接收Zombie ID 和猫的 ID 作为参数,调用 KittyContract 的 getKitty 函数以获取猫的 DNA,然后调用 feedAndMultiply 函数以将给定 Zombie 的 DNA 和猫的 DNA 相加取平均数以生成新的 DNA,并创建一个新的 Zombie。

qq_53633989的博客 1915

区块链行业中Solidity编程语言速成:带你了解以太坊智能合约

Solidity作为一种智能合约编程语言,在区块链行业中扮演着举足轻重的角色。它不仅为开发者提供了实现去中心化应用的强大工具,也为区块链技术的普及和应用提供了技术支持。通过对Solidity的学习,开发者可以深入理解智能合约的工作原理,从而更好地把握区块链技术的未来趋势。随着技术的不断进步和安全性问题的解决,Solidity无疑将在未来的区块链生态中占据更加重要的地位。

Luckyy_D的博客 2513

【区块链DAPP】智能合约概述

智能合约概述

小哲的博客 6519

区块链去中心化应用:DApp开发

区块链:一种分布式账本技术,通过去中心化的方式记录交易信息,确保数据的透明性和不可篡改性。DApp(去中心化应用):基于区块链技术构建的应用程序,其后端逻辑运行在区块链上,前端界面与用户交互。

shejizuopin的博客 1203

区块链开发:从智能合约到DApp

区块链技术正在重塑互联网的信任机制。本文从智能合约基础概念出发,深入讲解以太坊开发的核心技术,并以Web3.py为工具,手把手带你完成从智能合约编写到去中心化应用(DApp)开发的完整流程。通过本文,你将掌握Solidity智能合约开发、Web3.py与以太坊交互、DApp前端集成等核心技能。无论你是区块链新手还是希望系统学习DApp开发的工程师,本文都将为你打开Web3世界的大门。自动执行:满足条件时自动触发,无需人工干预不可篡改:一旦部署,代码无法修改透明公开:所有代码和交易记录公开可查去信任化。

七夜zippoe的博客 704

利用python-docx提取word的高亮部分

利用python-docx提取word的高亮部分 没有找到分享的文档,于是就自己研究了一下。 可以通过python里的python-docx去提取word内的高亮文本。 file=docx.Document(filepath) for para in file.paragraphs: for i in para.runs: #i.font.highlight_color设置了高亮颜色 if i.font.highlight_color is not None:

double_0221的博客 1809

电商秒杀场景下,如何用Redis+Lua脚本实现原子性库存扣减(附完整代码)

本文针对电商秒杀场景下的高并发与超卖难题,详细解析了如何利用Redis的原子性命令与Lua脚本实现可靠的库存扣减。通过对比多种方案,阐述了Redis+Lua作为黄金搭档的技术原理,并提供了从基础扣减到预扣减模型的完整代码实现,确保在高并发下数据的一致性与系统性能。

weixin_29219539的博客 502

步步为营从智能合约到 DApp

课程介绍 本课程从以太坊的基本知识点出发,由浅入深地学习以太坊的智能合约 Solidity,编写简单合约,并完成 DApp 的构建部署。 通过本系列课程的学习,将对智能合约有一个完整的认识,从零开始编写属于自己的智能合约,感受区块链技术带来的便利。 本课程分为四部分: 第一部分(第01课),智能合约市场概述; 第二部分(第02~05课),以太坊的智能合约 Solidity 的基础教程; 第三部...

GitChat 1601

Gazebo仿真UUV水下机器人:从环境搭建到避障算法实战

本文详细介绍了使用Gazebo仿真平台进行UUV水下机器人开发的全流程,涵盖从环境搭建、uuv_simulator配置、传感器集成到核心避障算法实战。通过搭建水下仿真实验室并实现基于激光雷达数据的反应式避障算法,为水下机器人算法验证与开发提供了高效、低成本的解决方案。

weixin_28840591的博客 263

第一章 | 为什么要学 Solidity?{介绍篇}

📚 第一章 | 为什么要学 Solidity?

白马区块Crypto100 1073

全志T113 Tina5.0开发:(零)源码下载&修改调试串口

本文章主要作为自己的笔记,如有错误欢迎指出$ repo start product-da-t113-tina-stable --all # 全部下载完成之后,创建分支运行过程可能会出现版本问题;rm -rf .repo //先删除试试( 我安装的是3.6版本)

u014428915的博客 1164

Emscripten安装(wasm编译)

5:配置对应环境变量--替换成自己对应的安装路径(2025最新的Emscripten工具链默认使用LLVM/WebAssembly标准工作流,java依赖已经移除了,所以以下java环境不配,需要使用java的手动添加即可---->emsdk install java-8-152-64bit。3:下载相应的依赖库---->emsdk install latest(我这里下的是最新的,如果有指定版本,把latest替换成版本号即可)6:测试是否成功---> emcc- v/em++ -v。

qq_31578301的博客 554

使用Python开发以太坊智能合约【DApp入门指南】

智能合约概述智能合约是运行在区块链上的自动化合约,能够执行预定的业务逻辑。以太坊是最流行的智能合约平台,提供了强大的开发和运行环境。Solidity基础Solidity是用于编写以太坊智能合约的编程语言,支持面向对象的编程风格。示例包括一个简单的投票合约,演示了如何创建提案、投票以及查询结果。使用Web3.py与以太坊交互Web3.py是一个Python库,允许与以太坊区块链进行交互。示例包括如何部署合约、进行投票以及查询提案。前端集成。

一键难忘的博客 3698

【YOLOv11改进- 主干网络】YOLOv11+WTConv(ECCV2024): 基于YOLOv11的主干网络改进,大感受野的小波卷积

论文提出了WTConv,这是一个使用级联小波分解的层,并执行一组小卷积核的卷积,每个卷积专注于输入的不同频率带,并具有越来越大的感受野。这个过程能够在输入中对低频信息给予更多重视,同时仅增加少量可训练参数。实际上,对于一个  的感受野,可训练参数数量只随着  的增长而呈对数增长。而WTConv与常规方法的参数平方增长形成对比,能够获得有效的卷积神经网络(CNN),其有效感受野(ERF)大小前所未有。

qq_41304809的博客 1401

Solidity开发智能合约

然后,作为合约的创造者——即“主席”,我们将为每个选项提供一个简称为“winningProposal()”的函数,用于返回获得最多投票的提案。启动服务器不需要web3.js,但是需要文件,所以引入Node.js的ts模块和circular-json将对象转换为字符串,因为对象中有循环引用,所以不能直接使用JSON,而是使用了CircularJSON。底层类是用java实现的。因为数据比较多,这里就不一一给出blockchain的数据了,感兴趣可以自己动手试一试,然后看一下blockchain文件中的数据。

通往IT大道的专栏 1667

数据资产可视化分析:PowerBI在大数据管理中的实战

目的:帮你搞懂“为什么数据资产需要可视化?”“PowerBI能帮企业解决什么问题?”,并掌握用PowerBI做大数据可视化的实战技巧。范围:覆盖数据资产定义、可视化分析原理、PowerBI核心功能(数据连接、建模、可视化)、零售企业实战案例,以及未来趋势与挑战。背景:为什么企业的数据像乱堆的玩具?核心概念:数据资产、可视化分析、PowerBI分别是什么?它们怎么配合?实战步骤:用PowerBI帮零售企业整理“销售玩具箱”,做出能指导决策的仪表盘;应用场景:不同部门怎么用这个“整理好的玩具箱”?

2501_92132293的博客 906

基于 Simulink 的 PV 光伏阵列功率发电系统仿真 Matlab

其中直流侧电压需要与光伏电池组件匹配,交流侧电压则需要与配电系统匹配,开关频率一般在几千赫兹左右,需要保证在一定范围内。根据实际需求,我们还可以通过增加负载,以及调节光照强度等方式,模拟不同的情况下系统的响应和性能表现。经过设置参数和各部分之间的传递和控制后,我们可以开始进行模型仿真。在仿真前,我们需要确定仿真时间和步长,并对整体模型进行编译。在建立完毕整体模型框架后,我们需要为每个组件设置参数,并进行传递和控制。首先,我们需要建立一个整体的模型框架,包括各个组件之间的关系和控制器的作用。

学习使你进步。 1128
上一篇: 【React】归纳篇(五)组件组合的使用 | 受控与非受控组件 | 组件的综合练习 | 获取表单数据
下一篇: 【React】归纳篇(六)组件对象的生命周期 | 实例 | 虚拟DOM与DOM Diff算法
蟹蟹蟹风流
蟹蟹蟹风流 优质创作者: 编程框架技术领域 优质创作者: 编程框架技术领域 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄11年 3万+粉丝 396原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蟹蟹蟹风流

期望和你分享一杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值