0%

Project-CryptoZombie僵尸世界NFT游戏

Pre:

在做完僵尸教程后,觉得很不错,所以想从头写一遍,写一个dapp练练手。
前端用vue,合约用solidity,部署到goerli测试网

在线Demo:

需要使用Chrome浏览器和Metamask钱包插件,连接goerli测试网

RPC Chain ID browser
https://goerli.infura.io/v3/ 5 https://goerli.etherscan.io

效果图:

20211129150336

20211129150410

测试流程:

  1. 在remix编写solidity

  2. 在remix直接部署合约到JavaScript VM,把要用到函数走一遍流程

  3. truffle部署到ropsten测试网

  4. vue编写代码调试,与合约交互

部署:

执行

1
truffle migrate --network ropsten

即可部署至Ropsten

20211129152415

部署完毕后,把json文件copy到前端里面,在代码实例化后就可以直接使用了。

Bug:

把遇到的bug列一下

truffle初始化错误:

1
truffle init

直接用上面的命令去初始化truffle项目时,可能遇到网络问题等原因,无法直接初始化,可以去github下载
git clone https://github.com/truffle-box/bare-box

truffle部署合约:

部署到测试网时,truffle migrate --network ropsten

1
2
# 报错
Error: Cannot find module '@truffle/hdwallet-provider'

解决办法: npm install @truffle/hdwallet-provider

1
2
3
# 报错
Error encountered, bailing. Network state unknown. Review successful transactions manually.
insufficient funds for gas * price + value

解决办法:要确保助记词和钱包对应得上,且钱包里有足够的Ether

语法:

把遇到的一些语法问题列一下

pure vs view:

pure比view更加严格

view读取存储,但不会修改

1
2
3
4
5
6
7
8
9
10
11
contract viewExample {

string state;

// other contract functions

function viewState() public view returns(string) {
//read the contract storage
return state;
}
}

pure可以被认为是返回值仅由它的参数(输入值)确定的子集。不会对存储进行读写操作,只会使用局部变量

1
2
3
4
5
6
7
8
9
10
11
contract pureExample {

// other contract functions

function pureComputation(uint para1 , uint para2) public pure returns(uint result) {
// do whatever with para1 and para2 and assign to result as below
result = para1 + para2;
return result;
}

}

When to use “View” and “Pure” in place of “Constant”

external vs public:

public - all can access

external - Cannot be accessed internally, only externally

internal - only this contract and contracts deriving from it can access

private - can be accessed only from this contract

external vs public best practices

array删除:

1
2
3
4
5
6
7
8
9
10
11
12
uint[] assets;
mapping(uint=>uint) indexOfAsset;

function removeAssetFromArray(uint _assetToDelete) {
uint index = indexOfAsset[_assetToDelete];
if (!index) return;

if (assets.length > 1) { // 把最后一项移到你需要删除的位置,进行覆盖
assets[index] = assets[assets.length-1];
}
assets.length--; // Implicitly recovers gas from last element storage
}

Efficient approach to delete element from array in Solidity

invalid opcode “0xfe”:

合约数组可能有越界访问的问题,这个时候多去remix把操作流程仔细走一遍,看看调用哪个函数会出错。

Refs: