想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!
这一篇分析一下metacoin的合约代码。
智能合约是一组数据和代码的集合,合约部署到链上之后会产生一个地址,外部经过该地址调用合约代码来改变或者查询合约的数据(状态)。
metacoin合约是用Solidity语言编写的,经过solc编译成字节码,而后在发生外部访问时被以太坊虚拟机EVM执行。
Solidity是一种跟Java很相似的语言,因此代码读起来也不怎么费劲。咱们先看一下MetaCoin.sol的代码,一行一行地看:
pragma solidity ^0.4.18;
第一行是声明Solidity的版本,保证代码的兼容性。
import "./ConvertLib.sol";
这一行经过import关键字导入外部类库ConvertLib。
contract MetaCoin {app
mapping (address => uint) balances; event Transfer(address indexed _from, address indexed _to, uint256 _value); ... ...
}
Truffle要求合约的名次必须和文件名一致,而且只能使用contract和library这两个关键字。紧接着声明了两个全局变量:
● balances:用于存储全部帐户的余额。这个变量是mapping类型,其实就理解为HashMap,key是address类型,value是uint类型。address类型大小是160bit,用于存储帐户地址或者合约地址。
● Transfer:这是一个event类型的变量,该事件会在sendCoin()方法中被触发。客户端能够经过watch()方法来监听区块链上触发的事件,用于跟踪交易。函数
function MetaCoin() public { balances[tx.origin] = 10000; }
接下来就是合约的构造函数了,合约的构造函数只会在建立合约时被调用一次,以后就永远不会被调用了(能够理解为new了一个全局的单例对象)。tx是一个全局变量,表示当前的transaction,也就是建立合约的这个transaction。因此执行这个构造函数就是往合约的创始人帐号里打了10000个MetaCoin。区块链
function sendCoin(address receiver, uint amount) public returns(bool sufficient) { if (balances[msg.sender] < amount) return false; balances[msg.sender] -= amount; balances[receiver] += amount; Transfer(msg.sender, receiver, amount); return true; }
接下来看sendCoin()函数:参数是接收人地址以及发送代币的数量,返回是否发送成功。Solidity的语法比较有意思,跟Java相比,Solidity的权限修饰符以及返回值都是写在右边的。。。
第一步就是判断发送人是否有足够的余额。msg也是一个全局变量,msg.sender就是此次调用发起人的地址。这些全局变量能够获取和当前transaction相关的一些区块链属性.ui
接下来的2行很好理解,发送帐号余额减小,接收帐号余额增长。紧接着下一行就是触发Transfer事件,从而外部监听者能够收到通知。spa
function getBalanceInEth(address addr) public view returns(uint){ return ConvertLib.convert(getBalance(addr),2); } function getBalance(address addr) public view returns(uint) { return balances[addr]; }
最后两个函数是查询接口,返回MetaCoin余额以及转换成ETH的余额。这里用到刚开始导入的ConvertLib类库,那咱们就来看看这个ConvertLib.sol:
pragma solidity ^0.4.4;code
library ConvertLib{对象
function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) { return amount * conversionRate; }
}
代码很是简单,就是把余额乘上一个转换率,以前传的转换率是2,也就是说一个MetaCoin值2个ETH。
最后咱们看下合约编译后的输出:接口