1.工具介绍
1.1 ganache
这个软件可以帮我们搭建一个私有的区块链,因为我们开发的时候,需要调试,测试也不可能在真实的区块链上实现,那样成本很高,部署合约都是需要gas费用的(手续费)。
1.2 metamask
是加密货币钱包,只不过它是以插件的形式安装在浏览器上的。
1.3 remix
一个在线合约编译平台,可以帮我们编译好的合约通过metamask部署到ganache的私有链上。
2.工具安装和使用
2.1 安装ganache
ganache的下载地址:Ganache - Truffle Suite
安装好后,我们只要启动ganache软件,私有链就搭建好了,它绑定的IP端口是HTTP://127.0.0.1:7545,我们可以通过这个IP端口访问区块链,并且已经为我们创建好了十个账户,每个账户都有100个eth,当然这是私有,你如果玩过游戏,你可以把它当作私服类似的。
2.2 安装metamask
接着我们来安装metamask,你可以打开浏览器的管理扩展程序功能(插件),直接搜索metamask进行安装,或者去官网:https://metamask.io/download/
安装好后,我们打开metamask,创建一个账户,当然你也可以导入ganache为你创建的账户。
2.3 metamask添加ganache私有链
点下面这个选择添加网络:
然后选择手动添加网络:
然后填入如下信息:
网络名称,可以自行取名,RPC URL就是我们ganache的IP和端口。链ID,输的时候会自动从ganache获取,根据提示输入即可。货币符号,因为是构建的以太坊私有链,所以是eth .
然后点保存,切换到我们的myeth网络来。
但是里面没有代币,我们需要导入ganache给我们分配的账号。
打开ganache,选择导出私钥
将私钥复制,然后打开metamask,选择账户,添加账户,通过导入私钥方式:
OK,你添加的这个账户有100eth:
接着我们来测试一下转账,从这个账户转50个币给另外一个地址 :
发送后,我们切换到ganache,注意不要关闭,因为这些数据都是临时的,关闭再打开会清空。
可以看到账户数量已变,另外也可以点blocks和transactions,查看这笔交易区块的具体数据。
2.4 remix部署合约到ganache私有链
我们打开Remix - Ethereum IDE这个网站,然后打开contracts目录下的_Storage.sol
这就是一个合约代码文件,sol结尾,右边就是具体代码,是用Solidity语言写的,如果你有其它编程语言基础的话,那么不难理解,代码功能就是创建了一个类,然后store函数接收一个数字,存在number里,然后retrieve返回这个数字,关于Solidity语言可以参考:Solidity — Solidity 0.8.20 文档
这个就是remix给我们的一个简单的示例。
我们先把这个合约编译一下,编译好生成的代码我们才可以部署上去:
左边点一个像是"刷新“的按钮,然后点 Compile 1_Storage.sol,编译好后,那个按钮会出现一个绿色的勾表示编译好了。
我们接着就可以部署了
左边点击箭头所指的图标,然后选择通过metamask方式部署,注意要加载到我们有余额的那个账户,因为部署需要手续费,如果不出来的话,metamask设置连接一下,然后remix里重新切换刷新一下:
OK:
接着,我们点下面的Deploy按钮部署。
但是部署失败,提示evm版本和ganache不兼容。我们来更改编译版本,先将remix换成中文,这样便于操作一点,左下角设置里更改。
然后我们,重新点编译按钮,选择高级设置,选择london版本,再编译一下。
然后再切换到部署按钮,点击部署,metamask弹出需要你确认的提示,点击确认。
这次部署OK(注意部署如果没反应,刷新一下,钱包也重新打开一下) 。
合约部署好后,你会得到一个合约地址,这个地址是随机生成给你的,你部署上去的代码也不能更改了。你重新部署也只会得到新的合约地址,原来地址中代码不可更改,这就是合约一部分特性。
3.调用合约:
合约部署上去了,我们怎么调用,前面说过了,ganache绑定了IP和端口,你可以看作是区块链通过这个和外面通信, 那么这个肯定有一套协议,我们需要部署合约,调用合约,或者转账之类的。都要基于这套协议,但是我们不可能自已从底层来写一套协议。
3.1 web3.js
这些工作,web3库已经帮我们写好了,我们只要使用相应的web3里的函数,就可以了,大大的减轻了我们的工作。
注意web3的版本和平台,我这里使用的web3.js库,当然还有其他语言的web3.php和web3.py等。
3.2 nodejs
为了使用web3.js我们得安装node.js,这个你先可以看作是asp.net php之类的一种东西,只不过它不是用自创的语言做后端,而是用javascript,我们做网页总得有个服务端,所以这里使用了nodejs,当然如果你想用客户端调用web3也行,得找到适用的web3.js版本,通过<script src=web3.js>之类的引用,并且还得注意避免nodejs专用"语法“,这里就不介绍了。
单纯的合约不叫Dapp,我们需要给用户使用,所以也得设计前端,对客户友好的操作界面,它们结合起来就叫Dapp,nodejs在这里充当前台功能。
nodejs下载地址:
https://nodejs.org/en选择LTS版本安装。
安装好后,命令输入node -v 有版本出现即成功:
然后我们输入npm -v,看一下npm有没有,npm 是nodejs自带的包管理工具。我们接下来,使用npm来安装web3.js包。
先随便建个文件夹,比如e盘test,我们命令行进入这个目录下,然后输入如下命令安装web3,
这里我们指定安装1.2.4版本。
npm install web3@1.2.4
(注意网络问题),安装好后,我们看到这个目录下生成了:
其中web3库就在node_modules目录里,node_modules 就是node项目依赖包所在目录, 我这个项目需要web3.js所有里面就有web3。
然后要使用的时候就用require('web3'),这句的意思是,从node_modules下寻找web3.js,找到就加载进来。
然后我们去web3.eth.Contract — web3.js 1.0.0 documentation
这里有各个版本的web3说明,我们找到对应的版本,查看合约调用方法1.2.4如下方法。
3.3 合约的地址和abi
我们需要合约的地址和abi,才可以定位到合约中的函数,然后调用。
合约abi编译成功时会给出,如下复制:
合约地址部署成功的时候会给出,如下复制:
3.4 合约调用代码
然后我们在e盘test目录下,创建一个test.js文件,如下代码:
var abi=[ //合约abi
{
"inputs": [],
"name": "retrieve",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "num",
"type": "uint256"
}
],
"name": "store",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
var conadr='0xcf384636d2a0d4044e5c68b785c9a89afa8619ca'; //合约地址
var Web3=require("web3"); //加载web3.js
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545")); //连接区块链
var myContract = new web3.eth.Contract(abi,conadr); //根据api和合约地址 生成合约对象
var accountFrom='0xff62cbC2f41bBa770F9A3180743D90B9D2Ad8445';//调用合约的个人地址
myContract.methods.store(1888).send({from:accountFrom}, function(error, transactionHash){ //执行合约的store方法存储一个数字
console.log(transactionHash);// 输出调用stroe方法,在区块中生成的那笔交易哈希
myContract.methods.retrieve().call().then(console.log); //调用retrieve方法获得你存在区链中的那个数字
});
把复制的api赋给api变量,合约地址赋给conadr变量。
然后,accountFrom就是,你要用哪个账号调用这个合约,就填那个账号地址,我这里填的第一个:
好,接着我们命令行,进入e盘test,输入node test.js运行这个js文件:
OK,输出1888,说明写入读取合约正常。
我们在ganache查看,调用store方法所花费的手续费对应的那笔交易 哈希:
和node输出的对上了,说明一切都正常执行。