Solidity_Core


Multi-Sigs

Multi-sigs is smart contract designed so that multuple signatures from different addresses are needed for transactions to be executed.
Thert are commonly used to wallet.Multi-sigs be a wallet since it can transfer and save funds. it’s called ‘multi-sigs’ because it typically need multiple signatures then can approve activitied from wallet. Since multi-sigs powered by multiple address, thay avoide a single point of failure, which makes it significantly harder for funds to be compromised. This designer provide higher degree of security for against lost or compromised key.

signle point failure

Consider the typcial EOAs contronaled by external actor(ie, someone outside the blockchain, typically human).
Picsee-20230609150312.png

Why EOAs has the potential for single point of failure?
Because the external actor’s key could be become compromised by a hacker phishing or stolen. Evan as bad, the provided key could be lost by external actor, meaning directly control over an address balance no longer exists.

2 of 3 multi-sigs contracts

Picsee-20230609151739.png
In multi-sigs setups, multi keys are required to aprove a transaction. smart contract requires 2-of-3 keys signature in order to approve and send transactions to the Ethereum.
Once we have the setups, it’s doesn’t matter whether one individual loses their keys, because others can will approve the transaction, kick out the compromised keys and re-add the compromised user under a new address.
seperator responsiability of ownership of address and its funds between multiple actors means the multi-sigs wallet is secure against signle point of failure. evan if there is malicious party in the multi-sigs, they would need corrupt a majority of the holders to compromised the wallet.
Picsee-20230609153906.png
the multi-sigs contract keep track owner 1,2 and 3,it configured with number of required comformations to move funds, 2 in this case.
Owner#1 sumbit a transaction and send 0.5 ETH to address. The transaction will be peding until enough confirmations to move forward. since this transaction only required 2 confirmations, it will be executed when Owner#3 confirmed.

Inheritance

As with many object-obrient languages, solidity incluces inheritance.
Picsee-20230609211411.png
In solidity, Inheritance required to use is keyword, As above figure, we can see b is a’s child or b is a’s sub-class.

multi-inheritance

Imagine that we have simple contract like below shows.

contract Token {
    mapping(address => uint) balances;
}

now, we use is keyword inheritance Token to Mytoken contract.

contract MyToken is Token {
    function mint(uint _amount) public {
        balances[msg.sender] += amount;
    }
}

We can see the veriable balances has aleady be inherited from Token. Now, If we also want use OnlyOwner modifier what we can do ? we just need use is keyword to inheritance anohter contract.

contract MyToken is Token, Ownable {
    function mint(uint _amount) public onlyOwner {
        balances[msg.sender] += amount;
    }
}

But if we need to overridding function of basic contract, we need use vitural keyword to declaring function
A function that is going to be overrridden by a child contract must be declared by virtual keyword

function foo() public pure virtual returns (uint) {
    return 10;
}

And the override function in child contract must be declared by override keyword.

function foo() public pure override returns (uint) {
    return 15;
}

⚠️ The overriding function must have the same visibility as the virtual function. If not the compiler will throw a TypeError: “Overriding function visibility differs”. Keep en eye out for that one!

Inheritance is a great way to follow the DRY (Don’t Repeat Yourself) principle of software development! 💯interesting reading about cleaning of code.

More information

Solidity and OOP
Calling super Class — By reading this website, we will know it don’t have super keywords in solidity.

instantiate interface

interface Enemy {
	function takeAttack(Hero.AttackTypes attackType) external;
}
...contract {
  function xx(address _address) public {
     Enemy enemy = Enemy(_address);
  }
}

ERC-20

We final come to the ERC-20 level. So what is ERC-20?
As we all knows, erevy tech industry need a rule/standard. because we need stanard to stand all the program, the standard in code lanuage is interface. previous setion we learn inherited and we know contract can be inherited by is keyword.
ERC-20 is Tech standard for Ethereum. The main use of ERC-20 is to increase the compatibility of ecosystem. Exchange like uniswap can build incredible applications because it create fundstructed based on ERC-20. this then triggers developers who use ERC-20 standard to develop. instand campatibility with uniswap and many other dapps.

ERC-20 simply use mapping to keep track fungible token. any token can exchange to other token. any one token is equal to any other token, no token have special right or behavior assoicated with them.

As we covered above, ERC-20 defines a common interface so that any application can use them in a standard way.

This simplifies and eases developers’ tasks, because they can proceed with their work, knowing that each and every new project won’t need to be redone every time a new token is released, as long as the token follows the rules.

This means you can build an app with full knowledge of the ERC-20 token standard and it immediately becomes compatible with any users and builders that are also using ERC-20! 🤝

The interface consists of a number of functions that must be present in every implementation of the standard, as well as some optional.

An ERC-20-compliant token contract must provide at least the following:

name, symbol, and decimals are all optional fields
totalSupply defines the current circulating supply of the tokens
balanceOf will return the balance for a particular user
transfer which is the bread and butter, transfer from one account to another
approve, transferFrom and allowance are methods for other contracts moving your funds

pragma solidity 0.8.4;

interface IERC20 {

    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);


    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

balances: mapping of token balances, by owner. Each transfer is a deduction from one balance and an addition to another balance.
allowances: mapping of allowances/delegate spending. This is a nested mapping in which the primary key is the address of the token owner which maps to a spender address and amount delegated to spend.

In ERC-20 compatible smart contracts, there are two ways to change balances:

transfer: A call to the transfer method is straightforward call to the contract’s transfer function, takes just one simple transaction.

approve-transferFrom: This way of transferring tokens is covered further in the next section! 👀

Decimal

Decimal is a measurements for cryptocurrencies, images that we have 1.3 dollar and we can split up into 3 cents and 1 dollar. so for know, the decimal of dollar is 2 that means the minimum value of the dollar is cents. Decimal is hurge problem in cryptocurrencies, splitting money becomes an even bigger problem because the currencies are expected to change dramatically in value. Think about if the dollar exploded in value, and in 5 years, 1 dollar is worth 100 of today’s dollars. In that world (provided that our currency isn’t changed), one cent would represent 1 dollar, and that would be the smallest quantity that dollars could represent. This is the situation that cryptocurrencies are faced with.

It would have a decimals value of 8. The smallest unit of measurement is called a Satoshi which is 0.00000001 bitcoin.

Ethereum tracks even more decimals and would have a decimals value of 18. The smallest uint of measurement is called Wei which is 0.000000000000000001 ether.

Most ERC20 tokens follow Ethereum’s convention and use a decimals field of 18.

Interact with ERC-20.

first we deploy ERC-20 contract.
Contract file

Contract name must equal to the Contract file name.

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract JiuCaiToken is ERC20 {
    uint constant _initial_supply = 100 * (10**18);
    constructor() ERC20("JiuCaiToken", "JCT") {
        _mint(msg.sender, _initial_supply);
    }
}

Deploy file

const {ethers} = require("hardhat");

async function main() {
  const [deployer] = await ethers.getSigners();

  console.log("Deploying contracts with the account:", deployer.address);

  const weiAmount = (await ethers.provider.getBalance(deployer.address)).toString();
  
  console.log("Account balance:", (await ethers.parseEther(weiAmount)));

  // make sure to replace the "GoofyGoober" reference with your own ERC-20 name!
  const Token = await ethers.getContractFactory("JiuCaiToken");
  const token = await Token.deploy();

  console.log("Token address:", await token.getAddress());
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
});

Airdrop file

// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const {ethers} = require("hardhat");
require('dotenv').config();

async function main() {
  const newSigner = await ethers.getSigner('0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199');
  const contract = await ethers.getContractAt('JiuCaiToken', '0x110e643933C29Fb790aA37B218A295dD416EC6Cb');
  // we can try signing the transaction with specified signature.
  // const newContract = await contract.connect(newSigner);
  // it will failed because it will be verified in ERC-20 Base Contract. Only can be called by owner who deployed the contract.
  // const res = await newContract.transfer('0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199', 111)
  const res = await contract.transfer('0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199', 111)
  console.log(res);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
});

Or we can interact with metamask via following this steps

Use IERC20

ba carefully use Interface, it must be implemented, in this case, we deployed ERC20 contract, then send address to IERC20.
other contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./IERC20.sol";

contract Chest {
   
    
    function plunder(address[] memory tokenAddresses) external {
        for (uint256 i = 0; i < tokenAddresses.length; i++) {
            address tokenAddress = tokenAddresses[i];
            // get the token contract
            IERC20 token = IERC20(tokenAddress);
            // get the blance of chest
            uint256 balance = token.balanceOf(address(this));
            // transfer balance form chest address to msg.sender
            token.transfer(msg.sender, balance);
        }
    }
    
}

test.js

const { assert } = require('chai');

describe('Chest', function () {
    let coinCreator, coinCreatorSigner, hunter, hunterSigner; 

    describe('storing erc20 tokens', () => {
        let token1;
        let token2;
        let chest;
        beforeEach(async () => {
            const ERC20 = await ethers.getContractFactory("ERC20FixedSupply");
            // deploy ERC20 contract with 10000 supply tokens.
            token1 = await ERC20.deploy(10000);
            await token1.deployed();
            // deploy Chest contract
            const Chest = await ethers.getContractFactory("Chest");
            chest = await Chest.deploy();
            await chest.deployed();

            const accounts = await ethers.provider.listAccounts();
            coinCreator = accounts[0];
            coinCreatorSigner = ethers.provider.getSigner(coinCreator);
            hunter = accounts[1];
            hunterSigner = ethers.provider.getSigner(hunter);
        });

        describe('storing some token1', () => {
            beforeEach(async () => {
                // transfer 1000 of 10000 token to chest address
                await token1.connect(coinCreatorSigner).transfer(chest.address, 1000);
            });

            it('should let us store token1 at the address', async () => {
                // get tokens of chest address
                const balance = await token1.balanceOf(chest.address);
                assert.strictEqual(balance.toString(), '1000');
            });

            describe('after plundering', () => {
                beforeEach(async () => {
                    // transfer token from chest address to hunterSigner
                    await chest.connect(hunterSigner).plunder([token1.address]);
                });

                it('should award the hunter the balance', async () => {
                    const hunterBalance = await token1.balanceOf(hunter);
                    assert.strictEqual(hunterBalance.toString(), '1000');
                });

                it('should remove the balance from the chest', async () => {
                    const balance = await token1.balanceOf(chest.address);
                    assert.strictEqual(balance.toString(), '0');
                });
            });
        });

    });
});

Wait problem

It must be carefull wait function. wait means waiting response until transaction be mined. but if u don’t have enough gas fee, it will running but not throw error for us.

NFT

Non-fungible token is NFT, all this means it is a token that unique and characteristics. NFT can present all of the type of asset in blockchain. NFT have a bit of standard, but the most popular is ERC721 and ERC1155(Different with two of that), it’s different with erc20, NFT used to store data off-chain, because it’s expensive to save uint256 in blockchain, can u imagine 5mb images? off-chain data has be called metadata and there have a standard for how to build metadata.
if we store metadata off-chain, where we stored ? is it store in centralized service ? if store in centralized service, it will be in danger, because if service stopped, the image will also can’t be vistored. foruntly, we store data in p2p, such like IFPS or Arweave.
IFPS use something called “content addressing” to store data in p2p network. that’s means data is store as hash of the content. when u looking for image, u actully provide IFPS with hash and it goes to find someone who is serving that hash. If the file contents retrieved don’t match the hash you requested, it is discarded out by the protocol.

📖 An excellent resource for learning more about IPFS is ProtoSchool. Specifically, take a look at this section on content addressing.

Solidity Storage layout

contract layout rule refers to the rule governing how contract’s variables are laid out in long-time memory. every contract has a memory space and it is permanent and real/writable storage space. contract can only read/write variables from itself. contract storage is divided up into 2^256 slots of 32bytes each. slots are contiguous and are refrence by index. staring at 0 to 2^256.All slots are initialized to a value of 0.

EVM storage memory is only directly accessible by these 32 byte slot.

Picsee-20230616180553.png

solidity will automatically mapp every define state variables of ur contract to a slot in storage in the order the state variables are declared. starting 0.

What is Endian-ness
Endian-ness refers to how computers store multi-byte values in memory (eg: uint256, bytes32, address), and there are two types of endian-ness: big-endian and little-endian.

Big-endian → last byte of binary representation of data type is stored first
Little-endian → first byte of binary representation of data type is stored first

For example take the hexadecimal number 0x01e8f7a1, a hexadecimal representation of the decimal number 32044961. How is this value stored in memory? Visually it will look like one of the diagrams below depending on the endian-ness.

Picsee-20230616181125.png

For below figures, we can see each slot have 32bytes memory space, so a and c will combine into same slot.
Picsee-20230616181149.png

Picsee-20230616181149.png

Library

Library are quiet similar to contract, they have same snytax Library{} and Contract{}. but the most different is Library can’t declare variables(do not have state).For this reason, library functions are most often pure which means they do not read/write state.
Library functions can only be called directly if they are marked as pure or view

The purpose of library is to saving gas and share code. try to use library because the library is auditabled and mainly deployed.

we have two ways to use library.
Picsee-20230620164010.png

Upgradable

In application dev are, we always so do the mvp first then keep iterable ablities for that to keep the app can be upgraded. since that we also need upgrad ability for smart contract.

Three part of upgradable contract

  1. Proxy contract(the contract user will directly access to interact)
  • keep status in contract itself
  • a contract based on ERC-1967 standard
  • this proxy contract is in charge of forwarding transaction to the implementation contract
  1. Implementation contract(the contract provider skeleton and data)
    This is where you instantiate your variables. Your proxy contract, via delegatecalls into this one, will give them value!
  2. Proxy admin(the contract links proxy and implementation)
    This contract holds authority over Proxy to upgrade the Proxy contract and thus link that proxy to a new implementation contract.
    Picsee-20230621200332.png
    The above diagram shows what is called the transparent proxy pattern. This pattern uses call, delegatecall and the three-contract design in order to achieve a super cool infrastrastructure. 💥

Here is a breakdown of the diagram flow, from the user perspective:

The user performs a call into the Proxy contract
That call hits the fallback function of the Proxy contract which is directly rigged to delegatecall into the Implementation contract address
In performing a delegatecall, the context of the Proxy contract is forwarded. This means that the storage of 0x1234.1111 will be directly affected by the logic of 0x1234.4444 (that’s the whole point of delegatecall!)
The logic from Implementation is performed on the state of Proxy and if the logic does not revert, the state is returned to Proxy which then returns a receipt to the original user
Transaction over! 🧾

Tutorial

  1. create v1 of contract based on @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.17;
    
    import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
    
    contract VendingMachineV1 is Initializable {
      // these state variables and their values
      // will be preserved forever, regardless of upgrading
      uint public numSodas;
      address public owner;
    
      function initialize(uint _numSodas) public initializer {
        numSodas = _numSodas;
        owner = msg.sender;
      }
    
      function purchaseSoda() public payable {
        require(msg.value >= 1000 wei, "You must pay 1000 wei for a soda!");
        numSodas--;
      }
    }
  2. publish contractv1 use upgrades.deployProxy, when we deploy the contract we can get the deploy address and implementation contract address via upgrades.erc1967.getImplementationAddress(proxy.address)
    const { ethers, upgrades } = require('hardhat');
    
    async function main() {
      const VendingMachineV1 = await ethers.getContractFactory('VendingMachineV1');
      const proxy = await upgrades.deployProxy(VendingMachineV1, [100]);
      await proxy.deployed();
    
      const implementationAddress = await upgrades.erc1967.getImplementationAddress(
        proxy.address
      );
    
      console.log('Proxy contract address: ' + proxy.address);
    
      console.log('Implementation contract address: ' + implementationAddress);
    }
    
    main();
  3. upgrade contract, we just need write new version of contract and directly upgrade contract via upgradeProxy.
    const { ethers, upgrades } = require('hardhat');
    
    // TO DO: Place the address of your proxy here!
    const proxyAddress = '';
    
    async function main() {
      const VendingMachineV2 = await ethers.getContractFactory('VendingMachineV2');
      const upgraded = await upgrades.upgradeProxy(proxyAddress, VendingMachineV2);
    
      const implementationAddress = await upgrades.erc1967.getImplementationAddress(
        proxyAddress
      );
    
      console.log("The current contract owner is: " + upgraded.owner());
      console.log('Implementation contract address: ' + implementationAddress);
    }
    
    main();

    The total Tutorial

Contract converting

As we know contract can convert to address, vice versa, but EVM didn’t check what address we pass through. so when we pass address to contract, we must be careful to use right address, otherwise we will get wrong contract.
such like

https://medium.com/coinmonks/solidity-contract-conversion-to-and-from-address-and-its-pitfall-bffc533a96eb

contract Proxy {
    uint256 x = 0;
    address public implementation;
    function changeImplementation(address _implementation) external {
        //implementation = _implementation;
        implementation = _implementation;
    }

    function changeX(uint256 _x) external {
        //(bool success, ) = implementation.delegatecall(msg.data);
        Logic3 logic = Logic3(implementation);
        logic.changeX(_x);
    }
}

contract Logic1 {
    uint256 public x = 0;

    function changeX(uint256 _x) external {
        x = _x;
    }
}

contract Logic3 {
    uint256 public x = 3;

    function changeX(uint256 _x) external {
        x = _x;
    }

    function tripleX() external {
        x *= 3;
    }
}

we have three contract and now we want to get address by implementation, for now we want to get Logic3 contract, so we just pass implementation address be Logic3 args.

const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");
const { assert } = require("chai");
const { ethers } = require("hardhat");

describe("Proxy", function () {
  async function deployFixture() {
    const Proxy = await ethers.getContractFactory("Proxy");
    const proxy = await Proxy.deploy();

    const Logic1 = await ethers.getContractFactory("Logic1");
    const logic1 = await Logic1.deploy();


    const Logic3 = await ethers.getContractFactory("Logic3");
    const logic3 = await Logic3.deploy();

    return { proxy, logic1, logic3 };
  }

  it("Should work with logic1", async function () {
    const { proxy, logic3 } = await loadFixture(deployFixture);
    await proxy.changeImplementation(logic3.address);
    assert.equal(await logic3.x(), 3);

    await logic3.changeX(52);
    assert.equal(await logic3.x(), 52);
  });

 
});

we deploy proxy and logic1 and logic3, so for now we change implementation address to logic3.address, and we can pass the test.
but if we change implementation address to logic1. In logic1 x initial value is zero, so do we will pass the test ????

it("Should work with logic1", async function () {
    const { proxy, logic3, logic1 } = await loadFixture(deployFixture);
    await proxy.changeImplementation(logic1.address);
    assert.equal(await logic1.x(), 3);

    await logic3.changeX(52);
    assert.equal(await logic1.x(), 52);
  });

Picsee-20230624221137.png
No, we can’t. because pass logic1 address to implementation, but the Contract didn’t check the address is 1 or 3, actually the evm can’t figure out what address we are passed in(for instance). so we get the logic1 contract not logic3 contract.

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:监管
ingenuity: 独创性


  TOC