solidity合约详解
Solidity 是一个面向合约的高级语言,其语法类似于JavaScript 。是运行在以太坊虚拟机中的代码。这里我们用的是remix编译环境。是一个在线的编译环境。地址为http://remix.ethereum.org
Solidity的合约类似于面向对象语言中的类。下面我们可以先创建一个合约。
pragma solidity ^0.4.7; contract a{ uint x; function set(uint num) public{ x = num; } function get() public returns(uint){ return x; } }
这里我们创建了一个合约a,合约中有一个状态变量 x,状态变量的储存方式是storage的,定义了两个函数 set 和 get,通过这两个函数就可以得到和修改x。同时也可以申明构造函数。
pragma solidity ^0.4.7; contract a{ uint x; function a() public{ x = 2; } function set(uint num) public{ x = num; } function get() public returns(uint){ return x; } }
构造函数的名字要和合约的名字相同,上面的构造函数中对 x 初始化为1。
pragma solidity ^0.4.7; contract b{ uint public y; } contract a{ uint x; b B = new b(); function a() public{ x = 1; } function set(uint num) public{ x = num; } function get() public returns(uint){ return x; } }
上面的合约中我们在合约a中创建了合约b的对象 B,就可以通过B来调用 b 中的变量和函数。
在合约中的函数可以被指定为外部的,公共的,内部的或私有的,默认是公共的。 对于状态变量,外部是不可能的,默认是内部的。
external:
外部功能是合约接口的一部分,这意味着它们可以通过其他合约和交易进行调用。 外部函数f不能在内部调用(即f()不起作用,但this.f()可以正常工作
public:
公共功能是合同接口的一部分,可以在内部或通过消息进行调用。 对于公共状态变量,生成自动Getters函数。
internal:
这些功能和状态变量只能在内部进行访问(即从当前合约或从其中获得的合约),而不使用这些变量。
private:
私有函数和状态变量只对其中定义的合约而不是衍生合约可见。
pragma solidity ^0.4.7; contract b{ uint public y; function set(uint num) public{ y = num; } function get() internal returns(uint){ return y; } } contract a{ uint x; b B = new b(); function a() public{ x = 1; } function set(uint num) public{ B.set(2); x = num; } function get() public returns(uint){ return x; } function gety() public returns(uint){ return B.get();//错误,在合约b中的函数 return B.y(); } }
编译器会自动为所有公共状态变量创建getter函数。因此编译器将生成一个名为y的函数,它不接受任何参数,并返回一个uint,即状态变量数据的值。
solidity也支持合约的继承,由于继承实现是代码复制。如果出现函数名重写,最终使用的是继承链上哪个合约定义的代码呢?实际执行时,依据的是最远继承的原则
pragma solidity ^0.4.7; contract b{ function data() public returns(uint){ return 1; } } contract a{ function data() public returns(uint){ return 2; } } contract c is a,b{ function call() public view returns(uint){ return data(); } } contract d is b,a{ function call() public view returns(uint){ return data(); } }
上面的代码中根据最远继承原则,合约 c 中 call 函数调用的是合约 b 的data 函数,合约 d 调用的是合约 a 的 data 函数