ETH源码学习(2)GetBalance
从这开始读,因为最简单。还能对重要的东西有所理解。如果是单节点debug,重启链之后余额会归零,所以最少要两个节点,同步区块就没这个问题了,具体原因还未知。 声明:eth版本:Geth/v1.10.7-unstable/darwin-arm64/go1.17.5,我对比了网上的一些文章,这块代码有改动,主要以下改变从BlockChain的snap中读account几乎放弃从trie中获取account,判断极为严苛,我想不到有什么情况能进入,应该是放弃了这层分析入口//命令 eth.getBalance('0x0d7dd6dbabee2ec9b325aa7aa8b42d75068e8597') //入口 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { //获取statedb state, _, err := s.b.StateAndHea...
Ether.js+Web3modal基础使用
1.说明现在网站会提供很多种钱包,web3modal可以提供统一的provider,不需要你操心太多东西用ether.js而不是web3.js的原因是简单,爽2.安装npm i web3modal npm i ethers //另外还需要安装对应wallet的包,自行搜索就行 3.连接钱包// MM默认就有,无需显式加入 const providerOptions = { walletconnect: { package: walletconnectProvider, options: { infuraId: "", }, }, }; //构建Web3Modal对象 const web3Modal = new Web3Modal({ //缓存provider cacheProvider: true, providerOptions, }); //连接wallet async function connect() { try { const web3ModalProvider = await web3Modal.connect(); provider = new ethers.pr...
签名:EIP712
//使用web3.js和eth-sig-util生成签名 import Web3 from "web3"; var sigUtil = require("eth-sig-util") const typedData = { //定义数据格式 types: { //固定格式,不要动,并且字段一个都不能少 //name:contract name //vaersion:版本号,如1.0随意 //chainId:当前链chainId //verifyingContract:合约地址 EIP712Domain: [ {name: 'name', type: 'string'}, {name: 'version', type: 'string'}, {name: 'chainId', type: 'uint256' }, {name: 'verifyingContract', type: 'address' }, ], //自定义自己业务的数据格式 Mail: [ {name: 'from', type: 'address'}, {name: 'to', type: 'address'},...
ETH源码学习(2)GetBalance
从这开始读,因为最简单。还能对重要的东西有所理解。如果是单节点debug,重启链之后余额会归零,所以最少要两个节点,同步区块就没这个问题了,具体原因还未知。 声明:eth版本:Geth/v1.10.7-unstable/darwin-arm64/go1.17.5,我对比了网上的一些文章,这块代码有改动,主要以下改变从BlockChain的snap中读account几乎放弃从trie中获取account,判断极为严苛,我想不到有什么情况能进入,应该是放弃了这层分析入口//命令 eth.getBalance('0x0d7dd6dbabee2ec9b325aa7aa8b42d75068e8597') //入口 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { //获取statedb state, _, err := s.b.StateAndHea...
Ether.js+Web3modal基础使用
1.说明现在网站会提供很多种钱包,web3modal可以提供统一的provider,不需要你操心太多东西用ether.js而不是web3.js的原因是简单,爽2.安装npm i web3modal npm i ethers //另外还需要安装对应wallet的包,自行搜索就行 3.连接钱包// MM默认就有,无需显式加入 const providerOptions = { walletconnect: { package: walletconnectProvider, options: { infuraId: "", }, }, }; //构建Web3Modal对象 const web3Modal = new Web3Modal({ //缓存provider cacheProvider: true, providerOptions, }); //连接wallet async function connect() { try { const web3ModalProvider = await web3Modal.connect(); provider = new ethers.pr...
签名:EIP712
//使用web3.js和eth-sig-util生成签名 import Web3 from "web3"; var sigUtil = require("eth-sig-util") const typedData = { //定义数据格式 types: { //固定格式,不要动,并且字段一个都不能少 //name:contract name //vaersion:版本号,如1.0随意 //chainId:当前链chainId //verifyingContract:合约地址 EIP712Domain: [ {name: 'name', type: 'string'}, {name: 'version', type: 'string'}, {name: 'chainId', type: 'uint256' }, {name: 'verifyingContract', type: 'address' }, ], //自定义自己业务的数据格式 Mail: [ {name: 'from', type: 'address'}, {name: 'to', type: 'address'},...
Subscribe to point
Subscribe to point
<100 subscribers
<100 subscribers
Share Dialog
Share Dialog
现在都用merkle tree 空投,记录下
用leaves一层又一层计算出root hash,验证时拿leaf+和该leaf有关的leaf再计算一遍root hash是否一样
具体说明看这里,肯定能懂
https://www.npmjs.com/package/merkletreejs
const { MerkleTree } = require("merkletreejs");
const keccak256 = require("keccak256");
//获取hash root
const leaves = ["地址1","地址2".....].map((x) => keccak256(x));
const tree = new MerkleTree(leaves, keccak256);
const root = tree.getHexRoot();
//获取leaf验证的路径
const leaf = keccak256("a");
const proof = tree.getProof(leaf);
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "hardhat/console.sol";
contract TestMPT is Ownable {
//记录root hash
bytes32 public saleMerkleRoot;
//是否领取过空投
mapping(address => bool) public claimed;
//设置root hash
function setSaleMerkleRoot(bytes32 merkleRoot) external onlyOwner {
saleMerkleRoot = merkleRoot;
}
//获取root hash
function getSaleMerkleRoot() external view returns(bytes32) {
return saleMerkleRoot;
}
//校验是否合法
modifier isValidMerkleProof(bytes32[] calldata merkleProof, bytes32 root,bytes memory leaf) {
require(
MerkleProof.verify(
merkleProof,
root,
keccak256(abi.encodePacked(leaf))
),
"Address does not exist in list"
);
_;
}
//获取airdrop
function getDrop(bytes32[] calldata merkleProof,bytes memory leaf,uint256 _amount)
external
isValidMerkleProof(merkleProof, saleMerkleRoot,leaf)
{
require(!claimed[msg.sender], "Address already claimed");
claimed[msg.sender] = true;
//todo 业务处理
}
}
const { ethers, artifacts, network } = require("hardhat");
const { writeAbiAddr } = require("./artifact_saver.js");
async function main() {
const contactName = "TestMPT";
const Greeter = await ethers.getContractFactory(contactName);
const greeter = await Greeter.deploy();
await greeter.deployed();
// 将abi address等信息保存到文件
const artifact = await artifacts.readArtifact(contactName);
await writeAbiAddr(artifact, greeter.address, contactName, network.name);
//设置root hash
const [owner] = await ethers.getSigners();
const counter = await ethers.getContractAt(
contactName,
greeter.address,
owner
);
await counter.setSaleMerkleRoot( "0xc7ec7ffb250de2b95a1c690751b2826ec9d2999dd9f5c6f8816655b1590ca544"
);
const merkleRoot = await counter.getSaleMerkleRoot();
//数组里的是获取leaf的验证路径,第二个参数是要验证的内容
//特殊情况,你只有一个leaf,那要传空数组
const result = await counter.getDrop(
[
"0x1575cc1dded49f942913392f94716824d29b8fa45876b2db6295d16a606533a4",
"0x6c42c6099e51e28eef8f19f71765bb42c571d5c7177996f177606138f65c0c2b",
"0xb0d6f760008340e3f60414d84b305702faa6418f44f31de07b10e05bf369eb3b",
"0x4c880bf401add28c4e51270dfe16b28c3ca1b3d263ff7c5863fc8214b4046364",
],
"0xc12ae5Ba30Da6eB11978939379D383beb5Df9b33"
);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
现在都用merkle tree 空投,记录下
用leaves一层又一层计算出root hash,验证时拿leaf+和该leaf有关的leaf再计算一遍root hash是否一样
具体说明看这里,肯定能懂
https://www.npmjs.com/package/merkletreejs
const { MerkleTree } = require("merkletreejs");
const keccak256 = require("keccak256");
//获取hash root
const leaves = ["地址1","地址2".....].map((x) => keccak256(x));
const tree = new MerkleTree(leaves, keccak256);
const root = tree.getHexRoot();
//获取leaf验证的路径
const leaf = keccak256("a");
const proof = tree.getProof(leaf);
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "hardhat/console.sol";
contract TestMPT is Ownable {
//记录root hash
bytes32 public saleMerkleRoot;
//是否领取过空投
mapping(address => bool) public claimed;
//设置root hash
function setSaleMerkleRoot(bytes32 merkleRoot) external onlyOwner {
saleMerkleRoot = merkleRoot;
}
//获取root hash
function getSaleMerkleRoot() external view returns(bytes32) {
return saleMerkleRoot;
}
//校验是否合法
modifier isValidMerkleProof(bytes32[] calldata merkleProof, bytes32 root,bytes memory leaf) {
require(
MerkleProof.verify(
merkleProof,
root,
keccak256(abi.encodePacked(leaf))
),
"Address does not exist in list"
);
_;
}
//获取airdrop
function getDrop(bytes32[] calldata merkleProof,bytes memory leaf,uint256 _amount)
external
isValidMerkleProof(merkleProof, saleMerkleRoot,leaf)
{
require(!claimed[msg.sender], "Address already claimed");
claimed[msg.sender] = true;
//todo 业务处理
}
}
const { ethers, artifacts, network } = require("hardhat");
const { writeAbiAddr } = require("./artifact_saver.js");
async function main() {
const contactName = "TestMPT";
const Greeter = await ethers.getContractFactory(contactName);
const greeter = await Greeter.deploy();
await greeter.deployed();
// 将abi address等信息保存到文件
const artifact = await artifacts.readArtifact(contactName);
await writeAbiAddr(artifact, greeter.address, contactName, network.name);
//设置root hash
const [owner] = await ethers.getSigners();
const counter = await ethers.getContractAt(
contactName,
greeter.address,
owner
);
await counter.setSaleMerkleRoot( "0xc7ec7ffb250de2b95a1c690751b2826ec9d2999dd9f5c6f8816655b1590ca544"
);
const merkleRoot = await counter.getSaleMerkleRoot();
//数组里的是获取leaf的验证路径,第二个参数是要验证的内容
//特殊情况,你只有一个leaf,那要传空数组
const result = await counter.getDrop(
[
"0x1575cc1dded49f942913392f94716824d29b8fa45876b2db6295d16a606533a4",
"0x6c42c6099e51e28eef8f19f71765bb42c571d5c7177996f177606138f65c0c2b",
"0xb0d6f760008340e3f60414d84b305702faa6418f44f31de07b10e05bf369eb3b",
"0x4c880bf401add28c4e51270dfe16b28c3ca1b3d263ff7c5863fc8214b4046364",
],
"0xc12ae5Ba30Da6eB11978939379D383beb5Df9b33"
);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
No activity yet