基于以太坊的次高价盲拍solidity智能合约(三)

基于以太坊的次高价盲拍solidity智能合约(三)

6.用于进行投票和支付的内部合约Arbitration

该内部合约用于卖家、买家、仲裁人对每一笔竞拍成功的交易进行投票,进行最后的支付操作。

合约结构如下:

	contract Arbitration{
		//仲裁人地址
	    address payable arbitrator;
	    //卖家地址
	    address payable seller;
	    //买家地址
	    address payable buyer;
	    //卖家获得票数
	    uint totalVotes2Seller;
	    //买家获得票数
	    uint totalVotes2Buyer;
	    //用于判断合约内的钱是否已经被支付给买家或者卖家
	    bool isSpent ;
	    //用于判断仲裁人、卖家和买家是否进行多次投票的数据结构
	    mapping(address=>bool) isAddressVoted;
	    
	    constructor(address payable _arbitrator,address payable _seller,address payable _buyer) payable public {
	        arbitrator=_arbitrator;
	        seller=_seller;
	        buyer=_buyer;
	    }
	}

辅助函数用于做代码阶段性测试:

 	function getBalance()public view returns(uint){
        return address(this).balance;
    }
    
    function getAritrationInfo()public view returns(address,address,address,uint,uint){
        return (arbitrator,seller,buyer,totalVotes2Seller,totalVotes2Buyer);
    }

由于买家、卖家、仲裁人只可见主合约Auction。所以,我们要通过合约Auction中的方法,调用内部合约Arbitration中的方法来实现投票已经支付功能。
也就是说在合约Arbitration中完成投票和支付功能的实现,在合约Auction中实现函数的调用。

投票和支付功能函数

	//修饰器,用于限定调用权限:只有仲裁人、卖家或者买家才可以投票
	modifier callerLimit(address _operator){
        require(_operator == arbitrator || _operator == seller || _operator == buyer);
        _;
    }
    //投票给卖家
    function vote2Seller(address _operator) public callerLimit(_operator) {
		//保证该Arbitration是未支付过的    
        require(!isSpent);
        //保证该投票者还没有投过票
        require(!isAddressVoted[_operator]);
        isAddressVoted[_operator]=true;
        
        //支付功能:如果卖家得票数大于等于2,即合约把本次竞拍的以太坊转给卖家
        if(++totalVotes2Seller==2){
            isSpent=true;
            seller.transfer(address(this).balance);
        }
    }
    //投票给买家
    function vote2Buyer(address _operator)  public callerLimit(_operator) {
    	//保证该Arbitration是未支付过的   
        require(!isSpent);
        //保证该投票者还没有投过票
        require(!isAddressVoted[_operator]);
        isAddressVoted[_operator]=true;
        
        //支付功能:如果卖家得票数大于等于2,即合约把本次竞拍的以太坊转给买家
        if(++totalVotes2Buyer==2){
            isSpent=true;
            buyer.transfer(address(this).balance);
        }
    }

功能函数实现之后,需要在主合约Auction中增添用户可以调用的函数接口:

contract Auction{
	...
	//投票给卖家
	function vote2Seller(uint _productIndex)public {
		//通过商品编号找到该商品对应的Arbitration实例
        Arbitration arb=proIndex2Arbitration[_productIndex];
        //调用合约内的功能函数
        arb.vote2Seller(msg.sender);
    }
    //投票给买家
    function vote2Buyer(uint _productIndex)public {
   		//通过商品编号找到该商品对应的Arbitration实例
        Arbitration arb=proIndex2Arbitration[_productIndex];
        //调用合约内的功能函数
        arb.vote2Buyer(msg.sender);
    }
}

同时编写辅助函数用于代码阶段性测试:

	function getArbitrationInfo(uint _productIndex) public view returns(address ,address,address,uint,uint){
		//利用商品编号找到对应的Arbitration实例
        Arbitration arb = proIndex2Arbitration[_productIndex];
        //然后通过合约Arbitration中的辅助函数来向主合约中返回信息
        return arb.getAritrationInfo();       
    }

7.尾语

这样一个关于盲拍的智能合约功能就已经实现了。大家可以自己模拟一些用户在Remix编辑器中进行测试。
由于之前我是使用solidity 0.4.24版本的编译器,所以在版本5的代码语法上有许多变化的地方。
出于“强迫症”,本合约遇到的改动罗列如下:

一、

	address payable xxx;

如果涉及到转账的地址,0.5.0版本必须在address关键字后追加payable关键字

二、

	function fun1(string memory xxx) ..{}

定义函数时,0.5.5版本像string这样的引用类型后必须加memory,不能省略。

三、

	Contract1 c1 = new Contract1;

0.4.24版本中,在合约内部创建其他合约实例的时候返回值可以用address类型变量来接收。但是在0.5.0版本中,必须以合约实例的变量来接受。

ps:
本人热爱图灵,热爱中本聪,热爱V神,热爱一切被梨花照过的姑娘。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!

后现代泼痞浪漫主义奠基人
公众号名称:后现代泼痞浪漫主义奠基人

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值