Eth

智能合约

January 26, 2022
Blockchain, Smart Contract
Eth, Evm

智能合约 #

智能合约wiki

(英语:Smart contract)是一种特殊协议,在区块链内制定合约时使用,当中内含了代码函数 (Function),亦能与其他合约进行交互、做决策、存储资料及发送以太币等功能。智能合约主要提供验证及执行合约内所订立的条件。智能合约允许在没有第三方的情况下进行可信交易。这些交易可追踪且不可逆转

安全问题 #

智能合约是“执行合约条款的计算机交易协议”。区块链上的所有用户都可以看到基于区块链的智能合约。但是,这会导致包括安全漏洞在内的所有漏洞都可见,并且可能无法迅速修复。

这样的攻击难以迅速解决,例如:

2016年6月The DAOEther的漏洞造成损失5000万美元,而开发者试图达成共识的解决方案。DAO的程序在黑客删除资金之前有一段时间的延迟。以太坊软件的一个硬分叉在时限到期之前完成了攻击者的资金回收工作。

以太坊智能合约中的问题包括合约编程Solidity、编译器错误、以太坊虚拟机错误、对区块链网络的攻击、程序错误的不变性以及其他尚无文档记录的攻击。

2018年4月22日, BeautyChain智能合约出现重大漏洞,黑客通过此漏洞无限生成代币,导致 BitEclipse (BEC)的价值接近归零。同月25日,SmartMesh出现疑似重大安全漏洞,宣布暂停所有SMT交易和转账直至另行通知,导致损失约1.4亿美金。28日,EOS被指可能存在BEC代币合约类似的整数溢出漏洞,但没消息详细说明。5月24日, BAI交易存在大量异常问题, 损失金额未知。8月22日, GODGAME 合约被黑客入侵,GOD智能合约上的以太坊总数归零。

合约开发、测试和部署 #

eth智能合约文档

vending machine(自动售货机): money + snack selection = snack dispensed, 给钱并选择小吃,小吃就会出来 – 是给刚好的钱,还是过量的钱,过量了在发放小吃的同时退钱呢?

合约长这样:

// 表明使用的sol版本 
pragma solidity 0.8.7;

// Solidity 合约类似于面向对象语言中的类。合约中有用于数据持久化的状态变量,和可以修改状态变量的函数。 调用另一个合约实例的函数时,会执行一个 EVM 函数调用,这个操作会切换执行时的上下文,这样,前一个合约的状态变量就不能访问了。
contract VendingMachine {

    // Declare state variables of the contract
    address public owner; // owner变量
    mapping (address => uint) public cupcakeBalances; // cupcakeBalances变量

    // 创建合约时,合约的构造函数会执行一次。构造函数是可选的。只允许有一个构造函数,这意味着不支持重载。
    // When 'VendingMachine' contract is deployed:
    // 1. set the deploying address as the owner of the contract
    // 2. set the deployed smart contract's cupcake balance to 100
    constructor() {
        owner = msg.sender; // 设置部署本合约的地址为合约所有者

        // address(this)是将this转型为地址吗?
        // this不是代表合约对象吗,还能转为address?
        cupcakeBalances[address(this)] = 100; // 设置蛋糕余量
    }

    // Allow the owner to increase the smart contract's cupcake balance
    function refill(uint amount) public { // public表示方法可导出
        require(msg.sender == owner, "Only the owner can refill."); // 如果前面的条件不成立,则报错,后面为内容;此处要求消息的发送者必须是本合约所有者
        cupcakeBalances[address(this)] += amount; // 补充蛋糕
    }

    // Allow anyone to purchase cupcakes
    function purchase(uint amount) public payable { // payable表示方法含有支付逻辑
        require(msg.value >= amount * 1 ether, "You must pay at least 1 ETH per cupcake"); // 此处要求每个蛋糕最少支付一个eth
        require(cupcakeBalances[address(this)] >= amount, "Not enough cupcakes in stock to complete this purchase"); // 此处要求蛋糕余量不小于需要的数量
        cupcakeBalances[address(this)] -= amount; // 本合约所有者减少蛋糕
        cupcakeBalances[msg.sender] += amount; // 消息发送者添加蛋糕
    }
}

address(this)

...