书上得来终觉浅,绝知此事要躬行-以太坊平台实战篇

        网上和书上的教程大多是在私有链单机CPU挖矿的情况,遗漏了实战环境中遇到的问题。接下来一步步的阐述实战经验,并结合理论分析。

        有些概念先介绍下
        transactionHash:交易的流水号,转账和执行合约方法都是交易。
        blockHash:根据区块内容计算的唯一哈希值
        blockNumber:区块号,按数字加1累加。

        分叉的情况,多块区块使用同个blockNumber,但不同blockHash。

        

                                                                                            矿机状态图

先看初学者的一段代码:

合约代码:

	contract Calucator {
	     function Calucator() public 
        {
	     }
       function addNumber(uint a,uint b) public  returns(uint k)
	     {
	               k= a+b;
	               returnk;
	     }
	 }	


Js代码:

	App.contracts.Calucator.deployed().then(function(instance) {
	       return instance.addNumber(1,2);
	}).then(function(result) {
	       console.log("result:"+result);
	});

预期控制台显示的结果是3,但是result的结果是:

result = {tx:"0x69ddf34a618cd621144fb26dd3e479a85c9ec0bb6c5e2ac76b6aefe9aa74bad5",receipt: {…}, logs:                  Array(0)}

调用合约的方法,返回的是交易hash,合约代码的返回值需要通过回调事件返回。

修改后的代码如下: 合约代码:

	contract Calucator {
		event  returnValue(
			address indexed _from,
			uint indexed  _value
		);
		function Calucator() public {
		}
		function addNumber(uint a,uint b) public 
		{
			uint k = a+b;
			emit returnValue(msg.sender,  k);
		}
	}

Js代码:

	eventCallBack:function(error, result){
		if(!error)
			console.log(result);
	},
	markAdopted: function() {
		var event;
		App.contracts.Calucator.deployed().then(function(instance){
		        event= instance.returnValue();
		        web3.personal.unlockAccount(web3.eth.accounts[0],'123456',999);
		        event.watch(App.eventCallBack);                    
		        return instance.addNumber(1,2);
		}).then(function(result){
		        console.log("result:"+result);
		});
	 }

如果搭建的是私有链环境,挖矿速度通常设置比较快,很快就可以捕获到事件的返回,但是在以太坊公有链上,需要等待十几秒的时间,打包区块时才执行合约代码触发回调事件。

然而,网上教程没有告诉你的是:事件回调后得到的区块hash并不是最终保存交易记录的区块的blockHash.原因是由于两个或者多个矿工几乎同时发现了一个区块引起的分叉。


        在某个时刻网络上的矿机同时挖出两个区块,blockNumber都为N+1,但是blockHash不一样,两个区块都会执行合约的代码,触发两次回调。一个区块是否最终得到确认保存在主链上需要等六个区块的确认,第N+7的区块生成时,才能最终确认哪个N+1的块是永久保存在主链上。



阅读更多

更多精彩内容