实验目的

  • 理解以太坊上的智能合约
  • 开发实现简单的智能合约
  • 部署以太坊上的智能合约

实验原理

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

在以太坊上,智能合约是一个运行在以太坊链上的程序。 它是位于以太坊区块链上一个特定地址的一系列代码(函数)和数据(状态)。

智能合约也是一个以太坊帐户,即合约帐户。 这意味着它们有余额,可以成为交易的对象。 但是,它们无法被人操控,它们是被部署在网络上作为程序运行着。 个人用户可以通过提交交易执行智能合约的某一个函数来与智能合约进行交互。 智能合约能像常规合约一样定义规则,并通过代码自动强制执行。 默认情况下,您无法删除智能合约,与它们的交互是不可逆的.以太坊上的智能合约基本生命周期可以分为开发、编译、部署和运行。

实验内容

编写投票合约

本实验实现了简单的投票合约示例,即VotingContract,基本结构为:

  • Option表示每个投票选项的名称和投票计数。addoption()可以增加新的选项;getOptionCount()获取当前的投票选项数目;getOption()获取特定的选项的具体信息。
    99 8888888
    struct Option {
            string OptionName;
            uint256 voteCount;
        }
        Option[] public options;
        function addOption(string memory _name) public {
            options.push(Option(_name, 0));
        }
        function getOptionCount() public view returns (uint256) {
            return options.length;
        }
        function getOption(uint256 _optionIndex) public view returns (string memory, uint256) {
            require(_optionIndex < options.length, "Invalid option index");
            Option memory option = options[_optionIndex];
            return (option.OptionName, option.voteCount);
        }
  • 投票由votes存储,通过映射讲地址和选项索引关联起来

    mapping(address => uint256) public votes;
  • 用户通过vote()进行投票,已经投票的用户无法再投票

    function vote(uint256 _optionIndex) public {
            require(_optionIndex < options.length, "Invalid option index");
            require(votes[msg.sender] == 0, "Already voted");
            options[_optionIndex].voteCount++;
            votes[msg.sender] = _optionIndex;
        }

部署和调用合约

对投票合约进行部署,修改js文件:

const VotingContract = artifacts.require("VotingContract");

module.exports = function(deployer) {
  deployer.deploy(VotingContract);
};

部署命令:

truffle compile
truffle develop
truffle migrate --reset

部署结果:

> Compiling .\contracts\lab.sol

> Artifacts written to E:\2023spring\blockchain\lab4\build\contracts
> Compiled successfully using:

   - solc: 0.8.20+commit.a1b79de6.Emscripten.clang

调用合约

  • 创建投票选项

    truffle(develop)> let contract = await VotingContract.deployed()
    undefined
    truffle(develop)> await contract.addOption("Option 1")
    {
      tx: '0x7736c02bd8c1801d1785efa78ac225ca00cb670fe94f564965e241072ed8349a',
      recei
      ...
      }
  • 投票

    truffle(develop)> await contract.vote(0);
    {
      tx: '
      ...
      }
  • 查看投票信息

    truffle(develop)> let optionCount = await contract.getOptionCount();
    undefined
    truffle(develop)> console.log("Option count:", optionCount.toNumber());
    Option count: 1
    undefined
    truffle(develop)> let option = await contract.getOption(0);
    undefined
    truffle(develop)> console.log("Option:", option[0], "Votes:", option[1].toNumber())
    Option: Option 1 Votes: 1
    undefined