以太坊智能合約實戰篇-創建并運行一個最簡單的轉賬合約
在位元幣網路中的每一筆轉賬交易都可以被記錄,而且無法篡改,這是位元幣最核心也是最具價值的特性,
受位元幣的啟發,以太坊創新性的提出了智能合約,將單純的轉賬交易泛化為可以支持復雜規則的合約,讓每筆合約的執行都被記錄在以太坊網路中,而且合約的執行結果無法被篡改,這就是以太坊相對于位元幣的核心特點,也是質的飛躍,
智能合約的作用可以說是無窮無盡,其中之一就是發行虛擬貨幣,下面,我們將一步一步演示如何使用智能合約發布虛擬貨幣,希望讀者可以和我一起思考,以太坊從哪里來,又到哪里去的這個深刻的問題,
- 初始化專案
在發行虛擬貨幣前,需要先給它取一個漂亮的名字,最近元宇宙(metaverse)的概念比較火,拾人牙慧,不如就稱它為metacoin,
使用下面的命令初始化專案
$ mkdir metacoin
$ cd metacoin
$ truffle init
初始化完成以后,metacoin檔案夾中將出現三個檔案夾和一個組態檔:
-
\contracts檔案夾用來存放智能合約源代碼,可以看到里面已經有一個sol檔案, -
\migrations檔案夾用來存放部署智能合約的腳本,可以看到里面已經有一個js檔案, -
\test用來存放測驗智能合約的代碼,支持js與sol測驗, -
truffle-config.js是Truffle的組態檔,在這里可以配置智能合約需要部署的以太坊網路的位置,
構建完成后的檔案夾結構如下圖所示:

- 創建合約
下面,我們創建一個合約和針對這個合約的測驗
$ truffle create contract Metacoin
$ truffle create contract MetacoinTest
此時,再來查看目錄結構,新增了兩個檔案,Metaconin.sol表示的就是合約檔案、metacoin_test.js表示的就是合約的測驗檔案:

正如下面這段代碼所示,使用truffle創建的合約檔案Metacoin.sol中,除了必要的宣告,并沒有包含任何合約邏輯,真正的合約邏輯,還需要我們自己來撰寫,
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract Metacoin {
constructor() public {
}
}
下面是一個可以運行的最簡單的合約,這個合約包含一個建構式和兩個普通函式,建構式用來給合約創建地址初始化10000枚Metacoin代幣,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];
}
}
請先不要過分糾結這個合約的各個技術細節,后面我們會專門規劃一篇文章對這個合約的技術細節進行解釋,
- 編譯合約
在合約的根目錄下,執行編譯命令:
truffle compile -all
如果不加
-all,默認編譯的是檔案夾中自從上次編譯依賴修改過的合約檔案,加上-all表示的是編譯所有的合約檔案,
構建成功以后,可以在/build目錄下找到編譯生成的檔案,這就是最終編譯形成的結果,以.json檔案表示的中間件,這個中間件就可以執行在以太坊EVM虛擬機之上,
- 合約部署
在migrations檔案夾下創建2_deploy_contracts.js,檔案中的內容如下所示,該檔案的目的是在執行后續部署命令(truffle migrate)時,部署MetaCoin.sol中包含的智能合約,下面的內容也不需要糾結,大概意思是引入Metacoin合約,然后部署到目標網路中去,
const Metacoin = artifacts.require("Metacoin");
module.exports = function(deployer) {
deployer.deploy(Metacoin);
};
然后,我們執行如下的命令進行合約部署:
$ truffle migrate
如果出了上述命令,不執行其他配置的話,肯定會報如下錯誤,下面的錯誤是說找不到網路去部署當前的合約,

這時,就需要使用我們以前安裝的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即可成功部署合約,

截圖內容顯示成功部署一個合約,花費了0.00497708的ETH,
- 與合約進行互動
我們要與本地ganache創建的智能合約網路中部署的智能合約進行互動,可以使用truffle提供的命令列工具進行,
使用下面的命令登錄truffle控制臺
$ truffle console
truffle(ganache)>
在控制臺中執行如下腳本命令,可以實時看到執行的結果:
# 獲得已經部署的MetaCoin的編譯碼
let instance = await Metacoin.deployed()
# 列印編譯碼物件
console.log(instance)
# 獲得當前網路中的所有賬戶
let accounts = await web3.eth.getAccounts();
# 獲得賬戶0的余額(10000)
let balance = await instance.getBalance(accounts[0]);
balance.toNumber();
# 獲得賬戶1的余額(0)
let 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進行以太坊網路的模擬,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/398933.html
標籤:區塊鏈
