远程购买商品智能合约solidity代码
远程购买商品需买家和卖家相互信任,在下面的例子中,买家和卖家必须将商品价值(1*value)的两倍(2*value作为定金)放入合约中作为代管。
由于没有办法确定货物是否到达买方,一旦发生这种情况,这笔钱就会被锁在合同中,直到买家确认收到了物品。
交易成功后,买家得到的是价值(1*value)和物品,而卖家得到的是价值的三倍(3*value,定金加商品价值)。这背后的想法是,双方都有解决问题的动机,否则他们的钱就永远锁定了。
这个合约当然不能解决问题,但它概述了如何在合约中使用类似状态机的结构。
下文代码在solidity官方英文文档基础上添加很多注释用于帮助加深理解。
pragma solidity ^0.8.4;
//安全的远程购买,Remix编写
contract Purchase{
uint public value;//商品价值
address payable public seller;//卖家地址
address payable public buyer;//买家地址
//枚举类型,不用加分号,用于标记交易状态
enum State{Created,Locked,Release,Inactive}
State public state;//定义枚举类型变量
//modifier类似于一个可以通用的函数供其他function重复调用,减少代码量
//_;可以放在modifier结构体{}内的任何位置来运行调用modifier的function代码
modifier condition(bool condition_){
require(condition_);
_;
}
//error用于解释操作失败的原因,可以继承,参数列表可以只定义数据类型或为空
//不能重载,不能作为控制流的一种手段,合约内部和外部均可定义。
//调用时必须用revert修饰,revert用于回退error中数据给调用者并回退当前调用中所有更改。
error OnlyBuyer();//仅有买家可以调用
error OnlySeller();//仅有卖家可以调用
error InvalidState();//当前交易状态为Invalid,不能调用
error ValueNotEven();//商品价格为不为偶数,需中止交易
modifier onlyBuyer(){
if(msg.sender != buyer)
revert OnlyBuyer();
_;
}
modifier onlySeller(){
if(msg.sender != seller)
revert OnlySeller();
_;
}
modifier inState(State state_){
if(state != state_)
revert InvalidState();
_;
}
//调用event可以将合约中某些内容的更改记录到日志(记录在区块链上),用关键字emit修饰调用
//事件(event)和日志不能在合约内部访问,可以被子合约调用
event Aborted();//标识中止交易状态
event PurchaseConfirmed();//标识交易发起
event ItemReceived();//标识交易确认
event SellerRefunded();//标识卖家退款事件
//构造函数,部署合约时调用,仅调用一次,初次调用该合约的地址默认为卖家并初始化卖价
//当前版本的address分为:address 和 payable address
//payable address支持.transfer和.send方法,用于发送ether
//payable address只能给payable address转账,而不能给address转账
constructor() payable{
seller = payable(msg.sender);
value = msg.value/2;
if((2*value)!=msg.value)
revert ValueNotEven();//value必须为偶数
}
//中止交易过程,给卖家退钱
function abort() external onlySeller inState(State.Created){
emit Aborted();
state = State.Inactive;
seller.transfer(address(this).balance);//由交易调用智能呢个合约中的function,伴随转账金额,所以此处需要退款给卖家
}
//发起交易(交易发起者置为买家),更改交易状态为Locked
function confirmPurchase() external
inState(State.Created) condition(msg.value == (2*value)) payable{
emit PurchaseConfirmed();
buyer = payable(msg.sender);//强制类型转换将buyer转换为payable address类型
state = State.Locked;
}
//确认交易,给买家转账1*value,更改交易状态为Release
function confirmReceived() external onlyBuyer inState(State.Locked){
emit ItemReceived();
state = State.Release;
buyer.transfer(value);
}
//交易退款,给卖家转账3*value,更改交易状态为Inactive
function refundSeller() external onlySeller inState(State.Release){
emit SellerRefunded();
state = State.Inactive;
seller.transfer(3*value);
}
}
来源(solidity官方英文文档0.8.13):https://docs.soliditylang.org/en/v0.8.13/solidity-by-example.html#id2
solidity官方中文文档0.8.0:https://learnblockchain.cn/docs/solidity/solidity-by-example.html#id5

浙公网安备 33010602011771号