以太坊开发(二)——metacoin合约代码分析

这一篇分析一下metacoin的合约代码。

智能合约是一组数据和代码的集合,合约部署到链上以后会产生一个地址,外部通过该地址调用合约代码来改变或者查询合约的数据(状态)。

metacoin合约是用Solidity语言编写的,通过solc编译成字节码,然后在发生外部访问时被以太坊虚拟机EVM执行。

Solidity是一种跟Java很类似的语言,所以代码读起来也不怎么费劲。我们先看一下MetaCoin.sol的代码,一行一行地看:

pragma solidity ^0.4.18;

第一行是声明Solidity的版本,保证代码的兼容性。

import "./ConvertLib.sol";

这一行通过import关键字导入外部类库ConvertLib。

contract MetaCoin {
	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相关的一些区块链属性,完整列表参见:

http://solidity.readthedocs.io/en/develop/units-and-global-variables.html

以太坊开发(二)——metacoin合约代码分析_第1张图片

接下来的2行很好理解,发送账号余额减少,接收账号余额增加。紧接着下一行就是触发Transfer事件,从而外部监听者可以收到通知。

	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;

library ConvertLib{
	function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount)
	{
		return amount * conversionRate;
	}
}

代码非常简单,就是把余额乘上一个转换率,之前传的转换率是2,也就是说一个MetaCoin值2个ETH。

最后我们看下合约编译后的输出:

以太坊开发(二)——metacoin合约代码分析_第2张图片

编译结果是用JSON的形式组织的,包含了EVM字节码以及供外部调用的ABI格式:

以太坊开发(二)——metacoin合约代码分析_第3张图片

以太坊开发(二)——metacoin合约代码分析_第4张图片

至此,metacoin的合约代码就分析完了,是不是很简单呢?下一篇分析一下metacoin的测试代码。

欢迎关注飞久微信公众号,一起探讨更多技术问题:

以太坊开发(二)——metacoin合约代码分析_第5张图片

你可能感兴趣的:(区块链)