Zhuang's Diary

言之有物,持之以恒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pragma solidity ^0.6.12;

contract AutoShop {
address[] autoAssets;
function createChildContract(string memory brand, string memory model) public payable {
// 增加检查:ether是否足够支付 car
address newAutoAsset = address(new AutoAsset(brand, model, msg.sender));
autoAssets.push(newAutoAsset);
}
function getDeployChildContracts() public view returns (address[] memory) {
return autoAssets;
}
}

contract AutoAsset {
string brand;
string model;
address owner;
constructor(string memory _brand, string memory _model, address _owner) public {
brand = _brand;
model = _model;
owner = _owner;
}
}

address newAutoAsset = address(new AutoAsset(...) 出发了一个交易,将子合约部署到区块链并返回合约地址。同时,将合约地址存储到数组 address[] autoAssets 中。

关联文档:

  1. 智能合约-CURD的详细分析
  2. 智能合约-自毁模式
  3. 智能合约-工厂合约模式
  4. 智能合约-名字登录模式
  5. 智能合约-退款方式

​ 工厂合约的地址如果经常变化,就必须追踪这些合约。在这种情况下,就可以使用名字登录模式,存储合约名到合约地址的映射mapping,同时提供根据合约名来查找合约地址的功能,甚至还可以追踪版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
pragma solidity ^0.6.12;

contract NameRegistry {
struct ContractDetails {
address owner;
address contractAddress;
uint16 version;
}
mapping(string => ContractDetails) registry;

function registerName(string memory name, address addr, uint16 ver) public returns (bool) {
// 版本号码从1开始
require(ver >= 1);
ContractDetails memory info = registry[name];
require(info.owner == msg.sender);
// 如果在当前的registry不存在的话,创建记录
if(info.contractAddress == address(0)) {
info = ContractDetails({
owner:msg.sender,
contractAddress:addr,
version:ver
});
} else {
info.version = ver;
info.contractAddress = addr;
}
// 修改 registry 里的记录
registry[name] = info;
return true;
}

function getContractDetails(string memory name) public view returns (address, uint16) {
return(registry[name].contractAddress, registry[name].version);
}
}

通过 getContractDetails(name) 获得合约地址和指定版本的合约。

关联文档:

  1. 智能合约-CURD的详细分析
  2. 智能合约-自毁模式
  3. 智能合约-工厂合约模式
  4. 智能合约-名字登录模式
  5. 智能合约-退款方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pragma solidity ^0.6.12;

contract SelfDesctructionContract {
address payable owner;

modifier ownerRestricted {
require (owner == msg.sender);
_;
}

// 构造函数
constructor() public {
owner = msg.sender;
}

// 使用ownerRestricted修饰符来限定只有合约的所有者才能调用该函数
function destructContract() public payable ownerRestricted {
selfdestruct(owner);
}
}

owner 必须可接受支付的回收的gas。

关联文档:

  1. 智能合约-CURD的详细分析
  2. 智能合约-自毁模式
  3. 智能合约-工厂合约模式
  4. 智能合约-名字登录模式
  5. 智能合约-退款方式

​ ERC721是比ERC20更复杂的标准,具有多个可选扩展名,并且分为多个合约。 OpenZeppelin合约提供了灵活的组合方式以及自定义有用的扩展。本文讲解以OpenZeppelin合约为目标对象。

构建ERC721代币合同

​ 我们将使用ERC721来跟踪游戏中的装备条目,每个条目都有各自独特的属性。 每当要奖励给玩家时,便会铸造(mint)并发送给他们。 玩家可以自由保留自己的代币,也可以与自己认为合适的其他人进行交易,就像区块链上的任何其他资产一样! 请注意,任何帐户都可以将awardItem称为铸造(mint)。 为了限制可以创建项目的帐户,我们可以添加访问控制

​ 合约如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

constructor() public ERC721("GameItem", "ITM") {}

function awardItem(address player, string memory tokenURI)
public
returns (uint256)
{
_tokenIds.increment();

uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);

return newItemId;
}
}

​ ERC721合约包括了标准扩展(IERC721MetadataIERC721Enumerable)。 这就是_setTokenURI方法的来源:我们使用它来存储项目的元数据。

​ 另请注意:与ERC20不同,ERC721缺少小数,因为每个令牌都是不同的,并且无法分区。

​ 新项目示例:

1
2
3
4
> gameItem.awardItem(playerAddress, "https://game.example/item-id-8u5h2m.json")
Transaction successful. Transaction hash: 0x...
Events emitted:
- Transfer(0x0000000000000000000000000000000000000000, playerAddress, 7)

​ 查询每个项目的所有者和元数据:

1
2
3
4
> gameItem.ownerOf(7)
playerAddress
> gameItem.tokenURI(7)
"https://game.example/item-id-8u5h2m.json"

​ 此tokenURI应该解析为一个类似于以下内容的JSON文档:

1
2
3
4
5
6
{
"name": "Thor's hammer",
"description": "Mjölnir, the legendary hammer of the Norse god of thunder.",
"image": "https://game.example/item-id-8u5h2m.png",
"strength": 20
}

​ 有关tokenURI元数据JSON架构的更多信息,请参考==>https://eips.ethereum.org/EIPS/eip-721

ERC721 合约的前置功能

​ ERC721可用的预设有ERC721PresetMinterPauserAutoId。它已预设为允许Token铸造(创建),停止所有令牌传输(暂停),并允许持有人焚毁(销毁)其Token。合同使用访问控制来控制对铸造和暂停功能的访问。部署合同的帐户将被授予minter 和pauser 角色,以及默认的admin角色。

​ 无需编写任何Solidity代码即可立即部署此合同。它可以原样用于快速原型制作和测试,但也适用于生产环境。

关联内容 ==> https://willzhuang.github.io/2019/07/04/ERC20-721Token的发行-冻结-多方签名功能

客户端

  1. Rust : https://github.com/openethereum/openethereum
  2. Go : https://github.com/ethereum/go-ethereumhttps://github.com/etclabscore/core-geth
  3. .Net : https://github.com/Nethereum/Nethereum
  4. C++ : https://github.com/ethereum/aleth
  5. ConsenSys & jp morganchase : https://github.com/ConsenSys/quorum
  6. burrow : https://github.com/hyperledger/burrow
  7. ethermint : https://github.com/ChainSafe/ethermint
  8. besu (Java) :https://github.com/hyperledger/besu
  9. Ionhttps://github.com/clearmatics/autonity

虚拟机

  1. JS : https://github.com/ethereumjs/ethereumjs-vm
  2. SSVM : https://github.com/second-state/SSVM
  3. WAVM : https://github.com/WAVM/WAVM
  4. evmone : https://github.com/ethereum/evmone
  5. Hera : https://github.com/ewasm/hera

大数据

  1. ethereum-etl : https://github.com/blockchain-etl/ethereum-etl
  2. GraphQL : https://github.com/ConsenSys/ethql
  3. Graph Node : https://github.com/graphprotocol/graph-node

安全

  1. mythril : https://github.com/ConsenSys/mythril
  2. truffle-security : https://github.com/ConsenSys/truffle-security
  3. sm : https://github.com/tjfoc/gmsm

隐私

  1. ZoKrates : https://github.com/Zokrates/ZoKrates
  2. AZTEC : https://github.com/AztecProtocol/AZTEC
  3. privacy-enabled-erc721 : https://github.com/centrifuge/privacy-enabled-erc721
  4. nightlite(JS) : https://github.com/EYBlockchain/nightlite

浏览器

  1. blockscout : https://github.com/poanetwork/blockscout
  2. MyEtherWallet : https://github.com/EthVM/EthVM
  3. dashboard : https://github.com/Alethio/ethstats-network-dashboardhttps://ethstats.io/
  4. lite : https://github.com/Alethio/ethereum-lite-explorerhttps://explorer.aleth.io/
  5. ERC721 token list : https://github.com/Alethio/explorer-plugin-opensea
  6. data scrap : https://github.com/Alethio/memento
  7. hyperledger : https://github.com/hyperledger/blockchain-explorer

客户端

  1. MyEtherWallet : https://github.com/MyEtherWallet/MyEtherWallet
  2. wallet-core (C++) : https://github.com/trustwallet/wallet-core
  3. MultiSigWallet : https://github.com/ConsenSys/MultiSigWallet
  4. ethsigner : https://github.com/PegaSysEng/ethsigner/

DApp Framework

  1. embark : https://github.com/embarklabs/embark
  2. openzeppelin-contracts : https://github.com/OpenZeppelin/openzeppelin-contracts
  3. TRUFFLE : https://github.com/trufflesuite
  4. ethereumjs-util : https://github.com/ethereumjs/ethereumjs-util
  5. aragonOS : https://github.com/aragon/aragonOS
  6. eth-crypto : https://github.com/pubkey/eth-crypto
  7. voting_dapp : https://github.com/maheshmurthy/ethereum_voting_dapp

事件

  1. eventeum : https://github.com/ConsenSys/eventeum

SDK

  1. web3.js : https://github.com/ethereum/web3.js
  2. java : https://github.com/web3j/web3j
  3. react : https://github.com/NoahZinsmeister/web3-react
  4. go : https://github.com/Alethio/web3-go, https://github.com/umbracle/go-web3

连接

  1. 雷电网络 : https://github.com/raiden-network/raiden
  2. 离线支付 : https://github.com/perun-network/go-perun
  3. Hyperledger (Ethereum & Quorum & fabric) : https://github.com/hyperledger/cactus

Token

  1. E-Money : https://github.com/IoBuilders/em-token
  2. 可仲裁Token : https://github.com/kleros/erc-792

Ethereum 2.0

  1. lighthouse : https://github.com/sigp/lighthouse
  2. explorer : https://github.com/Alethio/eth2stats-client