以太坊智能合约开发-创建并运行一个最简单的转账合约

以太坊智能合约开发-创建并运行一个最简单的转账合约

在比特币网络中的每一笔转账交易都可以被记录,而且无法篡改,这是比特币最核心也是最具价值的特性。

受比特币的启发,以太坊创新性的提出了智能合约,将单纯的转账交易泛化为可以支持复杂规则的合约,让每笔合约的执行都被记录在以太坊网络中,而且合约的执行结果无法被篡改,这就是以太坊相对于比特币的核心特点,也是质的飞跃。

智能合约的作用可以说是无穷无尽,其中之一就是发行虚拟货币。下面,我们将一步一步演示如何使用智能合约发布虚拟货币。希望读者可以和我一起思考,以太坊从哪里来,又到哪里去的这个深刻的问题。

  1. 初始化项目

在发行虚拟货币前,需要先给它取一个漂亮的名字。最近元宇宙(metaverse)的概念比较火,拾人牙慧,不如就称它为metacoin

使用下面的命令初始化项目

$ mkdir metacoin
$ cd metacoin
$ truffle init

初始化完成以后,metacoin文件夹中将出现三个文件夹和一个配置文件:

  • contracts文件夹用来存放智能合约源代码,可以看到里面已经有一个sol文件。

  • migrations文件夹用来存放部署智能合约的脚本,可以看到里面已经有一个js文件。

  • test用来存放测试智能合约的代码,支持jssol测试。

  • truffle-config.jsTruffle的配置文件,在这里可以配置智能合约需要部署的以太坊网络的位置。

构建完成后的文件夹结构如下图所示:

image-20211217215149242

  1. 创建合约

下面,我们创建一个合约和针对这个合约的测试

$ truffle create contract Metacoin
$ truffle create contract MetacoinTest

此时,再来查看目录结构,新增了两个文件,Metaconin.sol表示的就是合约文件、metacoin_test.js表示的就是合约的测试文件:

image-20211217215547579

正如下面这段代码所示,使用truffle创建的合约文件Metacoin.sol中,除了必要的声明,并没有包含任何合约逻辑,真正的合约逻辑,还需要我们自己来编写。

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Metacoin {
  constructor() public {
  }
}

下面是一个可以运行的最简单的合约,这个合约包含一个构造函数和两个普通函数,构造函数用来给合约创建地址初始化10000Metacoin代币,sendConin函数用来发送代币,getBalance函数用来参数提供账户地址中代币余额。

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract MetaCoin {
	mapping (address => uint) balances;

	event Transfer(address indexed _from, address indexed _to, uint256 _value);

	constructor() public {
		balances[tx.origin] = 10000;
	}

	function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
		if (balances[msg.sender] < amount) return false;
		balances[msg.sender] -= amount;
		balances[receiver] += amount;
		emit Transfer(msg.sender, receiver, amount);
		return true;
	}

	function getBalance(address addr) public view returns(uint) {
		return balances[addr];
	}
}

请先不要过分纠结这个合约的各个技术细节,后面我们会专门规划一篇文章对这个合约的技术细节进行解释。

  1. 编译合约

在合约的根目录下,执行编译命令:

truffle compile -all	

如果不加-all,默认编译的是文件夹中自从上次编译依赖修改过的合约文件,加上-all表示的是编译所有的合约文件。

构建成功以后,可以在/build目录下找到编译生成的文件,这就是最终编译形成的结果,以.json文件表示的中间件,这个中间件就可以执行在以太坊EVM虚拟机之上。

  1. 合约部署

migrations文件夹下创建2_deploy_contracts.js,文件中的内容如下所示,该文件的目的是在执行后续部署命令(truffle migrate)时,部署MetaCoin.sol中包含的智能合约。下面的内容也不需要纠结,大概意思是引入Metacoin合约,然后部署到目标网络中去。

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

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

然后,我们执行如下的命令进行合约部署:

$ truffle migrate

如果出了上述命令,不执行其他配置的话,肯定会报如下错误,下面的错误是说找不到网络去部署当前的合约。

image-20211201094051637

这时,就需要使用我们以前安装的ganache-cli对以太坊网络进行模拟,来进行网络部署。

根据前面的提示,使用一下的命令来启动本地测试网络:

$ ganache-cli.cmd -p 7545 --networkId 5777 --chainId 1337

待上述命令启动后,打开项目下的truffle-config.js文件,寻找并配置下面这个字段。通过这种方式,可以告诉truffle部署的目标网络在本地的哪个端口。

development: {
    host: "127.0.0.1",     // Localhost (default: none)
    port: 7545,            // Standard Ethereum port (default: none)
    network_id: "5777",       // Any network (default: none)
},

然后,在执行truffle migrate即可成功部署合约。

image-20211201094838664

截图内容显示成功部署一个合约,花费了0.00497708的ETH。

  1. 与合约进行交互

我们要与本地ganache创建的智能合约网络中部署的智能合约进行交互,可以使用truffle提供的命令行工具进行。

使用下面的命令登录truffle控制台

$ truffle console
truffle(ganache)>

在控制台中执行如下脚本命令,可以实时看到执行的结果:

# 获得已经部署的MetaCoin的编译码
let instance = await Metacoin.deployed()

# 打印编译码对象
console.log(instance)

# 获得当前网络中的所有账户
let accounts = await web3.eth.getAccounts();

# 获得账户0的余额(10000let balance = await instance.getBalance(accounts[0]);
balance.toNumber();

# 获得账户1的余额(0let balance2 = await instance.getBalance(accounts[1]);
balance2.toNumber();

# 将余额由账户0转移至账户1
let result = await instance.sendCoin(accounts[1], 10, {from: accounts[0]})
console.log(result)

# 获得账户0的余额(9990,由于gas费用非常低,所以还是显示9990)
balance = await instance.getBalance(accounts[0]);
balance.toNumber();

# 获得账户1的余额(10)
balance2 = await instance.getBalance(accounts[1]);
balance2.toNumber();

到此,全部结束,账户0中的10000Metacoin来自于最初合约创建的时候,然后账户0转账10Metacoin给账户1,账户0剩余9990Metacoin

补充:

前面我们使用的以太坊模拟器ganache-cli是命令行形式运行的,当然也可以用可视化版本的Ganache进行以太坊网络的模拟。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
 

)">
< <上一篇
下一篇>>