Solidity_Core


Governance

Decentralization protocol are in consistent evolution from the moment they are published relased. When we publish contract if we want to improve or upgrade the contract, we need all of users who are focused on the contract/token know what we need to do, and get the agreement. This is Governance protocol. it only allowed who have token of the contract can cast vote to decide agree or not. after the agreement larger than thershould, we can execute the preset action.
Governor Repository
To follow along, clone this repository: MintGovernance.

In this repository, you’ll find two contracts:

MyGovernor - a contract built from the openzeppelin governor wizard. This Governor is configured to have a 1 block voting delay and voting period. To make things simpler it does not include a Timelock, although it should be noted that this is standard practice in governance.
MyToken - a token which is built to work together with the governor standard. You can re-create it by toggle the Votes checkbox on the openzeppelin erc20 wizard.
Setup
Once you clone the repository, you can run npm i to install all the depedencies
Then, you can run npx hardhat test to run the unit tests
You should see all test cases passing
Let’s take a look at the unit tests in the repository, what are they doing? Let’s break it down step by step.

  1. Deployment
    This first section is being used to deploy the contracts:
const transactionCount = await owner.getTransactionCount();

// gets the address of the token before it is deployed
const futureAddress = ethers.utils.getContractAddress({
  from: owner.address,
  nonce: transactionCount + 1
});

const MyGovernor = await ethers.getContractFactory("MyGovernor");
const governor = await MyGovernor.deploy(futureAddress);

const MyToken = await ethers.getContractFactory("MyToken");
const token = await MyToken.deploy(governor.address);

☝️ First we need to deploy the MyGovernor and MyToken contracts. This looks pretty standard, except for the piece where we need to calculate the futureAddress and provide it to MyGovernor on deployment. Let’s talk about that part.

When deploying contracts you’ll often find yourself in situation where one contract needs to know the other contract’s address on deployment and vice-versa. With our setup, this makes sense because the governor contract depends on the token for voting and the token depends on the governance for its mint function.

To get around this issue we calculate the address of the token contract ahead of time. We can do this because contract addresses are deterministic. They are the keccak hash of the address deploying the contract and the nonce for that particular address. You can see those are the two parameters that ethers is requiring us to pass in for the getContractAddress utility. We can, ahead of time, figure out what the contract address will be provided it is deployed in the following transaction.

  1. Delegation
    This probably seems like a silly step, but when you’re using token governance, its standard to delegate your votes to someone who can then use that voting power. In our case, the owner address receives 10000 tokens when they deploy the token and they want to delegate that voting power to themselves. So this transaction looks like this:

await token.delegate(owner.address);
The owner is delegating the weight of 10000 tokens to themselves to vote with.

  1. Proposing
    Once we are ready, we can make a new proposal on the governance system. We could encode any kind of call data or value on this proposal, and we can even specify multiple targets. In our case we’re trying to mint an extra 25000 tokens to the owner:
const tx = await governor.propose(
  [token.address],
  [0],
  [token.interface.encodeFunctionData("mint", [owner.address, parseEther("25000")])],
  "Give the owner more tokens!"
);

const receipt = await tx.wait();
const event = receipt.events.find(x => x.event === ‘ProposalCreated’);
const { proposalId } = event.args;
☝️ Here we create a proposal to mint 25000 tokens to the owner (by using parseEther here we’re taking advantage of the fact that the ERC20 token uses 18 decimals, just like ether). In order to lookup the state of the proposal and vote, we need the proposalId which is something that is emitted when the proposal is created. We grab the proposalId out of the event arguments.

We also need to wait for the block voting delay:

// wait for the 1 block voting delay
await hre.network.provider.send(“evm_mine”);
In our case we just need to wait one block before we can start voting on the proposal. This is something you can configure using the OpenZeppelin Governor Wizard

  1. Vote on the Proposal
    As the owner with 10000 tokens we have the executive power to push this proposal through. Let’s go ahead and vote on this proposal so we can execute it:

const tx = await governor.castVote(proposalId, 1);
This transaction will cast a vote as the owner with a weight of 10000 tokens. This will be enough for the vote to be successful! Normally, the next step would be to queue this proposal in the Timelock to wait for some period before execution. In this case, we’re not using a Timelock so we can go ahead and execute this proposal after the voting period has ended.

  1. Execute the Vote
    The execute function looks up the proposal by hashed parameters, so we’ll need to pass in our parameters here again for it to go look them up:
await governor.execute(
  [token.address],
  [0],
  [token.interface.encodeFunctionData("mint", [owner.address, parseEther("25000")])],
  keccak256(toUtf8Bytes("Give the owner more tokens!"))
);

This will execute our proposal! If successful, the owner should now have 35000 tokens because the governance proposal will target the ERC20 token and pass in the calldata to mint 25000 tokens. Amazing! 🤩

🏁 Your Goal: Govern on Goerli
We just walked through the entire flow in the unit test cases and can see how the governor standard works. Your goal is to now get this deployed and executed on the Goerli test network. You can do this by:

Add a Goerli URL and private key to the hardhat config (here’s the hardhat config docs) so that you can interact with the test network through Hardhat.
Re-configure MyGovernor to use a different voting period. A 1 block waiting period works for unit tests, but it would be too quick on goerli. This is the second argument passed to GovernorSettings. See the OpenZeppelin Wizard on how this is configured.
Once you’ve setup your goerli network, use the scripts/deploy.js script by running npx hardhat run scripts/deploy.js –network goerli. This should deploy the two contracts.
You’ll need to build several more scripts to run through steps 2-5 above. Be sure to:
delegate the votes to yourself
create a proposal
vote on the proposal
execute the proposal
When you are building the scripts to run through governance, make use of the ethers.getContractAt method which will allow you to specify a contract name and where it is deployed. This way you can build scripts that interact with the existing MyGovernor and MyToken contracts after you’ve deployed them.

How to set up on-chain governance,GovernanceApiGovernance Wizard

aka

ethereum: 以太坊
Blockchain: 区块链
Crypto: 加密
crytocurrencts: 加密货币
decentralized: 去中心化
bitcoin: 比特币,第一个基于区块链技术实现的加密货币
fiancial incentives: 金融奖励
mining the rewards: 挖矿
deterministic: 确定性
pseudorandom: 伪随机
collsion resistant: 抗碰撞
consensus: 共识,一个网络对数据的状态达成共识。
censorship:审查
bribe: 贿赂
drill home: 钻研
relatively travel:相对较小的
infeasible: 不可能
symmetric: 对称
digital signature: 数字签名
RSA: 非对称加密的经典实现
ECDSA: bitcoin采用的非对称加密算法
ether: 以太币
address: 交易发起方类似于ip, bitcoin 使用checksum and base58, ethereum is last 20 bytes of the hash of the public key.
Enforcement: 执行
consensus rules: 共识规则
consensus mechanisms:协商一致
inter-changeable: 可互换的
cumulative: 积累型
nakamoto consensus: 最长的chain将是其他节点接受的一个真正的链,他是由一条链积累的工作所决定的。
txs: transactions.
pos: proof of stack, pos中,参与者需要持有一定数量的crytocurrency,参与记账过程,相比pow,pos不需要大量的算力
pow: proof of work,miners通过计算来添加txs和block,需要消耗算力。可以增加security of blockchain
merkle root:默克尔根,用来验证和确认交易是否被篡改。
underlying: 底层
hashcash: Hashcash工作量证明功能由Adam Back于 1997 年发明,并建议用于反 DoS 用途
Byzantine General’s Problem: 在p2p场景下,如何证明每个机器都是在工作的。
manipulate: 操作
Genesis Block: 第一个加入到区块链中的块,初始块
cost-effective: 成本效益
UTXO:Unspent Transaction Output, 未使用的交易
Retrospective: 回顾
vulnerable: 脆弱的
light nodes: 轻节点 (存储块头的轻节点)
full nodes:完整节点(常规节点)
achieve nodes: 归档节点, 完整节点(已验证的存档节点)
bandwidth: 带宽
configure: 配置
variables: 变量
discrepancies: 差异
tradeoffs: 权衡利弊
contrast: 对比
unfakeable: 不可伪造
replicate: 复制
Satoshi: “Satoshi” refers to the smallest unit of the cryptocurrency Bitcoin
individual: 个人
multitude: 众多的
aggregate: 总数
expedite: 加快
hefty prize : 巨额奖金
controlled supply: 受控供应
intentional: 故意的
quirk: 怪癖
denial: 否认
distinguish: 辨别
preceding: 前面
emerge: 出现
hierarchically: 层次分明
intimidating: 令人生畏的
underneath: 底下
infacting:连接
concatenate: 串联
optimization: 优化
inconsistencies: 不一致
deveration: 推导
arbitrary: 随意的
immutable: 不可变
implications: 含义
ledger: 账本
traversal: 遍历
PMTs: Partricia Merkle tries
sealed: 密封.
Permenant: 永恒的
Ephemeral: 短暂的
Constantly: 不断的
prefixes: 前缀
recursion: 递归
portion: 部分
adjacent: 邻近的
neat mechanisms: 整洁的机制
consists: 包含
crowdfunding: 众筹
parse: 解析
intimidated: 吓坏
deterministic: 确定性
infrastructure: 基础设施
constrain: 限制
reside: 贮存
presence: 存在
cencership: 审查制度
auditable:可审查
Ubiquitous: 无处不在
barries: 障碍
curb: 抑制,阻止
comprehend: 理解
easy as pie: 易如反掌
explicitly:明确的
clause: 条款
neutrality;中立
arbitrary: 随意的
EVM: Etherrum Virtual Machine
Stale/Orphan block: 陈旧/孤立块,是指在一个区块同时被矿工挖掘出,区块可能会出现临时分叉,未能被选为有效区块的区块被称为stale/Orphan block,在Etherum中此类区块又称为Ommer block,是Etherrum作为鼓励和奖励矿工为安全做出贡献的机制。
emulate: 模仿
underlying: 潜在的
monetary: 货币
fixed: 固定的
Arithmetic: 算术
benchmarking: 基准测试
discrepancies: 差异
philosophy: 理念
Ethereum improvement proposal: EIP, Ethereum 改进提案
first and foremost: 首先
specification: 规范
adhere: 符合
impromptu: 即兴
compatible: 兼容的
contentious: 有争议的
overHead:高昂的
collateral: 抵押物
intuitively: 直观的
re-orged: 重组
manual:手动的
intervention: 干涉
canonical: 经典的
shifted: 转移
denomination: 面值
demand: 需求
circumventing: 规避
deflationary: 通缩
deprecated: 弃用
redunant: 多余的
tampered: 被篡改
EOAs: Extended owned account.
Vulnerability: 漏洞
JSON-RPC: remote procedure call(rpc) protocal that uses JSON to encode message.
exclusively: 只,仅仅 equied to only
instruction: 指令
term: 术语
boilerplate: 样板
pioneer: 先锋
lucrative: 有利可图
mnemonic: 助记词
configured: 配置
specified: 指定的
analogues: 相似的
discarded: 丢弃
underscore preceding: 前下划线
snippet: 片段
dire consquences: 可怕的后果
unsigned integer: 无符号整数
allocated: 分配的
resilient: 弹性的
LIFO: 堆栈结构,it’s have pushing and poping
destructure: 解构
parenthesis: 括号
exception: 异常
declared: 声明
ephermal: 短暂的
ABI: application binary interface, that’s bridge connected compilers and applications.
writing up a to b: 连接a到b
pass into: 传递……进
repercurssion: 反应
padded out: 填充到
replay to: 转发到
associative array: 关联数组
brute force search: 暴力搜索
hit the nail on the head : 一针见血
Nested: 嵌套
maintaining: 维护
Escrows: 托管
treadoff: 权衡
peroid of inactivity: 不活跃期
compromised: 损坏/妥协
expenditure: 支出
consent: 同意
DRY: don’t repeat yourself
WET: write everything twice
AHA: avoid hasty abstraction
audited: 审核
Standalone: 独立的
comma-separated: 逗号分离
vice-versa: 反之亦然
fungible: 可替换的
deduction: 减少
delegate: 代表
tremendously: 极大的
crowdsale: 众筹
mint: 铸造
precision: 精细
criteria: 标准
acronym: 首字母
proposition: 主张
rigorously: 严格的
regradless: 无论
governance:监管


  TOC