diff --git a/c/sudt_contracts.h b/c/sudt_contracts.h index 9ddb04cd..5c831364 100644 --- a/c/sudt_contracts.h +++ b/c/sudt_contracts.h @@ -147,8 +147,8 @@ int transfer_to_any_sudt_gas(const uint8_t* input_src, const size_t input_size, Transfer `sudt_id` token from `from_id` to `to_id` with `amount` balance. NOTE: This pre-compiled contract need caller to check permission of `from_id`, - currently only `solidity/erc20/SudtERC20Proxy.sol` is allowed to call this - contract. + currently only `solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.sol` is + allowed to call this contract. input: ====== @@ -163,13 +163,6 @@ int transfer_to_any_sudt(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, size_t* output_size) { - /* Contract code hash of `SudtERC20Proxy.ContractCode` - => 0x43a008ec973b648bd71ad67e6b66f2be8a6fa88e89c7dad046c948b00aa866aa */ - static const uint8_t sudt_erc20_proxy_contract_code_hash[32] = { - 0x43, 0xa0, 0x08, 0xec, 0x97, 0x3b, 0x64, 0x8b, 0xd7, 0x1a, 0xd6, - 0x7e, 0x6b, 0x66, 0xf2, 0xbe, 0x8a, 0x6f, 0xa8, 0x8e, 0x89, 0xc7, - 0xda, 0xd0, 0x46, 0xc9, 0x48, 0xb0, 0x0a, 0xa8, 0x66, 0xaa, - }; /* Contract code hash of `SudtERC20Proxy_UserDefinedDecimals.ContractCode` => 0xde4542f5a5bd32c09cd98e9752281f88900a059aab7ac103edd9df214f136c52 */ static const uint8_t @@ -183,13 +176,13 @@ int transfer_to_any_sudt(gw_context_t* ctx, const uint8_t* code_data, } uint8_t code_hash[32] = {0}; blake2b_hash(code_hash, (uint8_t*)code_data, code_size); - if (memcmp(code_hash, sudt_erc20_proxy_contract_code_hash, 32) != 0 && - memcmp(code_hash, + if (memcmp(code_hash, sudt_erc20_proxy_user_defined_decimals_contract_code_hash, 32) != 0) { ckb_debug("The contract is not allowed to call transfer_to_any_sudt"); debug_print_data(" got code hash", code_hash, 32); - debug_print_data("expected code hash", sudt_erc20_proxy_contract_code_hash, + debug_print_data("expected code hash", + sudt_erc20_proxy_user_defined_decimals_contract_code_hash, 32); return ERROR_TRANSFER_TO_ANY_SUDT; } diff --git a/docs/Addition-Features.md b/docs/Addition-Features.md index 0c94e54b..957ae686 100644 --- a/docs/Addition-Features.md +++ b/docs/Addition-Features.md @@ -3,7 +3,7 @@ * pre-compiled contract - Add `recover_account` for recover any supported signature - Add `balance_of_any_sudt` for query the balance of any sudt_id account - - Add `transfer_to_any_sudt` for transfer value by sudt_id (Must collaborate with SudtErc20Proxy.sol contract) + - Add `transfer_to_any_sudt` for transfer value by sudt_id (Must collaborate with SudtERC20Proxy_UserDefinedDecimals.sol contract) - Add `eth_to_godwoken_addr` for convert ETH address to polyjuice contract address (godwoken short address) ### `recover_account` Spec @@ -41,7 +41,7 @@ See: [Example](../polyjuice-tests/src/test_cases/evm-contracts/RecoverAccount.so output[0..32] => amount ``` -See: [Example](../solidity/erc20/SudtERC20Proxy.sol) +See: [Example](../solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.sol) ### `transfer_to_any_sudt` Spec @@ -49,7 +49,7 @@ See: [Example](../solidity/erc20/SudtERC20Proxy.sol) Transfer `sudt_id` token from `from_id` to `to_id` with `amount` balance. NOTE: This pre-compiled contract need caller to check permission of `from_id`, - currently only `solidity/erc20/SudtERC20Proxy.sol` is allowed to call this contract. + currently only `solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.sol` is allowed to call this contract. input: ====== @@ -61,7 +61,7 @@ See: [Example](../solidity/erc20/SudtERC20Proxy.sol) output: [] ``` -See: [Example](../solidity/erc20/SudtERC20Proxy.sol) +See: [Example](../solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.sol) ### `eth_to_godwoken_addr` Spec diff --git a/polyjuice-tests/src/test_cases/sudt_erc20_proxy.rs b/polyjuice-tests/src/test_cases/sudt_erc20_proxy.rs index 62e3b685..55e68b5b 100644 --- a/polyjuice-tests/src/test_cases/sudt_erc20_proxy.rs +++ b/polyjuice-tests/src/test_cases/sudt_erc20_proxy.rs @@ -12,7 +12,6 @@ use gw_store::traits::chain_store::ChainStore; use gw_store::{chain_view::ChainView, Store}; use gw_types::{bytes::Bytes, packed::RawL2Transaction, prelude::*}; -const SUDT_ERC20_PROXY_CODE: &str = include_str!("../../../solidity/erc20/SudtERC20Proxy.bin"); const SUDT_ERC20_PROXY_USER_DEFINED_DECIMALS_CODE: &str = include_str!("../../../solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.bin"); @@ -25,6 +24,7 @@ fn test_sudt_erc20_proxy_inner( block_producer_id: u32, decimals: Option, ) -> Result<(), TransactionError> { + let decimals = decimals.unwrap_or(18); let from_script1 = build_eth_l2_script([1u8; 20]); let from_script_hash1 = from_script1.hash(); let from_short_address1 = &from_script_hash1[0..20]; @@ -49,55 +49,28 @@ fn test_sudt_erc20_proxy_inner( .mint_sudt(CKB_SUDT_ACCOUNT_ID, from_short_address3, 2000000) .unwrap(); - // Deploy sUDT ERC20 Proxy - match decimals { - None => { - // ethabi encode params -v string "test" -v string "tt" -v uint256 000000000000000000000000000000000000000204fce5e3e250261100000000 -v uint256 0000000000000000000000000000000000000000000000000000000000000001 - let args = format!("000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000204fce5e3e25026110000000000000000000000000000000000000000000000000000000000000000000000{:02x}0000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027474000000000000000000000000000000000000000000000000000000000000", new_sudt_id); - let init_code = format!("{}{}", SUDT_ERC20_PROXY_CODE, args); - let _run_result = deploy( - generator, - store, - state, - creator_account_id, - from_id1, - init_code.as_str(), - 122000, - 0, - block_producer_id, - 1, - ); - print!("SudtERC20Proxy.ContractCode.hex: 0x"); - for byte in _run_result.return_data { - print!("{:02x}", byte); - } - println!(); - } - Some(decimals) => { - // Deploy SudtERC20Proxy_UserDefinedDecimals - // encodeDeploy(["erc20_decimals", "DEC", BigNumber.from(9876543210), 1, 8]) - // => 0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000024cb016ea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e65726332305f646563696d616c7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034445430000000000000000000000000000000000000000000000000000000000 - let args = format!("00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000024cb016ea00000000000000000000000000000000000000000000000000000000000000{:02x}00000000000000000000000000000000000000000000000000000000000000{:02x}000000000000000000000000000000000000000000000000000000000000000e65726332305f646563696d616c7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034445430000000000000000000000000000000000000000000000000000000000", new_sudt_id, decimals); - let init_code = format!("{}{}", SUDT_ERC20_PROXY_USER_DEFINED_DECIMALS_CODE, args); - let _run_result = deploy( - generator, - store, - state, - creator_account_id, - from_id1, - init_code.as_str(), - 122000, - 0, - block_producer_id, - 1, - ); - print!("SudtERC20Proxy_UserDefinedDecimals.ContractCode.hex: 0x"); - for byte in _run_result.return_data { - print!("{:02x}", byte); - } - println!(); - } + // Deploy SudtERC20Proxy_UserDefinedDecimals + // encodeDeploy(["erc20_decimals", "DEC", BigNumber.from(9876543210), 1, 8]) + // => 0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000024cb016ea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e65726332305f646563696d616c7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034445430000000000000000000000000000000000000000000000000000000000 + let args = format!("00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000024cb016ea00000000000000000000000000000000000000000000000000000000000000{:02x}00000000000000000000000000000000000000000000000000000000000000{:02x}000000000000000000000000000000000000000000000000000000000000000e65726332305f646563696d616c7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034445430000000000000000000000000000000000000000000000000000000000", new_sudt_id, decimals); + let init_code = format!("{}{}", SUDT_ERC20_PROXY_USER_DEFINED_DECIMALS_CODE, args); + let _run_result = deploy( + generator, + store, + state, + creator_account_id, + from_id1, + init_code.as_str(), + 122000, + 0, + block_producer_id, + 1, + ); + print!("SudtERC20Proxy_UserDefinedDecimals.ContractCode.hex: 0x"); + for byte in _run_result.return_data { + print!("{:02x}", byte); } + println!(); let contract_account_script = new_account_script(state, creator_account_id, from_id1, false); let script_hash = contract_account_script.hash().into(); @@ -263,7 +236,7 @@ fn test_sudt_erc20_proxy_inner( "313ce567".to_string(), &format!( "00000000000000000000000000000000000000000000000000000000000000{:02x}", - decimals.unwrap_or(18) + decimals ), ), // totalSupply() @@ -403,31 +376,6 @@ fn test_sudt_erc20_proxy_user_defined_decimals() { let new_sudt_script = build_l2_sudt_script([0xffu8; 32]); let new_sudt_id = state.create_account_from_script(new_sudt_script).unwrap(); - assert_eq!( - test_sudt_erc20_proxy_inner( - &generator, - &store, - &mut state, - creator_account_id, - new_sudt_id, - block_producer_id, - Some(8) - ), - Ok(()) - ); -} - -#[test] -fn test_sudt_erc20_proxy() { - let (store, mut state, generator, creator_account_id) = setup(); - let block_producer_script = build_eth_l2_script([0x99u8; 20]); - let block_producer_id = state - .create_account_from_script(block_producer_script) - .unwrap(); - - let new_sudt_script = build_l2_sudt_script([0xffu8; 32]); - let new_sudt_id = state.create_account_from_script(new_sudt_script).unwrap(); - assert_eq!(CKB_SUDT_ACCOUNT_ID, 1); assert_eq!( @@ -438,7 +386,7 @@ fn test_sudt_erc20_proxy() { creator_account_id, new_sudt_id, block_producer_id, - None + Some(8) ), Ok(()) ); diff --git a/solidity/erc20/README.md b/solidity/erc20/README.md index 5ae8421f..1a348fb2 100644 --- a/solidity/erc20/README.md +++ b/solidity/erc20/README.md @@ -1,7 +1,5 @@ For security reason, developers should only use this [SudtERC20Proxy_UserDefinedDecimals bytecode](./SudtERC20Proxy_UserDefinedDecimals.bin) which code hash will be checked in `transfer_to_any_sudt` pre-compiled contract. -Note: SudtERC20Proxy.sol will be deprecated. - ## Compile Solidity Contract in ethereum/solc:0.8.7 docker image Here is the method that we compile SudtERC20Proxy_UserDefinedDecimals.sol. ```sh diff --git a/solidity/erc20/SudtERC20Proxy.bin b/solidity/erc20/SudtERC20Proxy.bin deleted file mode 100644 index 4553733e..00000000 --- a/solidity/erc20/SudtERC20Proxy.bin +++ /dev/null @@ -1 +0,0 @@ -6080604052348015620000125760006000fd5b5060405162001a9e38038062001a9e8339818101604052810190620000389190620001e5565b5b83600360005090805190602001906200005492919062000094565b5082600460005090805190602001906200007092919062000094565b508160016000508190909055508060026000508190909055505b5050505062000431565b828054620000a2906200032e565b90600052602060002090601f016020900481019282620000c6576000855562000117565b82601f10620000e157805160ff191683800117855562000117565b8280016001018555821562000117579182015b82811115620001165782518260005090905591602001919060010190620000f4565b5b5090506200012691906200012a565b5090565b62000130565b808211156200014c576000818150600090555060010162000130565b50905662000430565b60006200016c6200016684620002b4565b62000289565b905082815260208101848484011115620001865760006000fd5b62000193848285620002f6565b505b9392505050565b600082601f8301121515620001b15760006000fd5b8151620001c384826020860162000155565b9150505b92915050565b600081519050620001de8162000412565b5b92915050565b600060006000600060808587031215620001ff5760006000fd5b600085015167ffffffffffffffff8111156200021b5760006000fd5b62000229878288016200019c565b945050602085015167ffffffffffffffff811115620002485760006000fd5b62000256878288016200019c565b93505060406200026987828801620001cd565b92505060606200027c87828801620001cd565b9150505b92959194509250565b600062000295620002a9565b9050620002a3828262000367565b5b919050565b600060405190505b90565b600067ffffffffffffffff821115620002d257620002d1620003cf565b5b620002dd8262000400565b90506020810190505b919050565b60008190505b919050565b60005b83811015620003175780820151818401525b602081019050620002f9565b8381111562000327576000848401525b505b505050565b6000600282049050600182168015156200034957607f821691505b6020821081141562000360576200035f6200039e565b5b505b919050565b620003728262000400565b810181811067ffffffffffffffff82111715620003945762000393620003cf565b5b80604052505b5050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b565b6000601f19601f83011690505b919050565b6200041d81620002eb565b811415156200042c5760006000fd5b5b50565b5b61165d80620004416000396000f3fe60806040523480156100115760006000fd5b50600436106100b95760003560e01c806370a082311161007257806370a08231146101a957806395d89b41146101d95780639f8dfb59146101f7578063a457c2d714610215578063a9059cbb14610245578063dd62ed3e14610275576100b9565b806306fdde03146100bf578063095ea7b3146100dd57806318160ddd1461010d57806323b872dd1461012b578063313ce5671461015b5780633950935114610179576100b9565b60006000fd5b6100c76102a5565b6040516100d4919061110d565b60405180910390f35b6100f760048036038101906100f29190610f70565b61033f565b60405161010491906110f1565b60405180910390f35b61011561036e565b60405161012291906111f6565b60405180910390f35b61014560048036038101906101409190610f1e565b610380565b60405161015291906110f1565b60405180910390f35b6101636104aa565b6040516101709190611212565b60405180910390f35b610193600480360381019061018e9190610f70565b6104b8565b6040516101a091906110f1565b60405180910390f35b6101c360048036038101906101be9190610eb4565b610584565b6040516101d091906111f6565b60405180910390f35b6101e16106b2565b6040516101ee919061110d565b60405180910390f35b6101ff61074c565b60405161020c91906111f6565b60405180910390f35b61022f600480360381019061022a9190610f70565b61075e565b60405161023c91906110f1565b60405180910390f35b61025f600480360381019061025a9190610f70565b610876565b60405161026c91906110f1565b60405180910390f35b61028f600480360381019061028a9190610edf565b6108a5565b60405161029c91906111f6565b60405180910390f35b6060600360005080546102b790611367565b80601f01602080910402602001604051908101604052809291908181526020018280546102e390611367565b80156103305780601f1061030557610100808354040283529160200191610330565b820191906000526020600020905b81548152906001019060200180831161031357829003601f168201915b5050505050905061033c565b90565b600061035f61035261093a63ffffffff16565b848461094763ffffffff16565b60019050610368565b92915050565b6000600160005054905061037d565b90565b6000610393848484610b2263ffffffff16565b6000600060005060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005060006103ea61093a63ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054905082811015151561046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046690611172565b60405180910390fd5b6104988561048161093a63ffffffff16565b858461048d91906112a3565b61094763ffffffff16565b60019150506104a356505b9392505050565b6000601290506104b5565b90565b60006105756104cb61093a63ffffffff16565b8484600060005060006104e261093a63ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505461056a919061124c565b61094763ffffffff16565b6001905061057e565b92915050565b600061058e610e1e565b6002600050548160006002811015156105d0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200201909081815260200150508273ffffffffffffffffffffffffffffffffffffffff16816001600281101515610631577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020020190908181526020015050610647610e40565b602081604084600060f0600019f115156106615760006000fd5b80600060018110151561069d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020020151925050506106ad5650505b919050565b6060600460005080546106c490611367565b80601f01602080910402602001604051908101604052809291908181526020018280546106f090611367565b801561073d5780601f106107125761010080835404028352916020019161073d565b820191906000526020600020905b81548152906001019060200180831161072057829003601f168201915b50505050509050610749565b90565b6000600260005054905061075b565b90565b600060006000600050600061077761093a63ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054905082811015151561083c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610833906111d5565b60405180910390fd5b61086561084d61093a63ffffffff16565b85858461085a91906112a3565b61094763ffffffff16565b600191505061087056505b92915050565b600061089661088961093a63ffffffff16565b8484610b2263ffffffff16565b6001905061089f565b92915050565b6000600060005060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549050610934565b92915050565b6000339050610944565b90565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156109b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b0906111b4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2290611151565b60405180910390fd5b80600060005060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000508190909055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b1491906111f6565b60405180910390a35b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8b90611193565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610c06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bfd90611130565b60405180910390fd5b610c24610c1761093a63ffffffff16565b8383610e1863ffffffff16565b610c2c610e62565b600260005054816000600481101515610c6e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200201909081815260200150508373ffffffffffffffffffffffffffffffffffffffff16816001600481101515610ccf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200201909081815260200150508273ffffffffffffffffffffffffffffffffffffffff16816002600481101515610d30577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002019090818152602001505081816003600481101515610d7b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020020190908181526020015050610d91610e40565b602081608084600060f1600019f11515610dab5760006000fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610e0891906111f6565b60405180910390a350505b505050565b5b505050565b6040518060400160405280600290602082028036833780820191505090505090565b6040518060200160405280600190602082028036833780820191505090505090565b604051806080016040528060049060208202803683378082019150509050509056611626565b600081359050610e97816115f0565b5b92915050565b600081359050610ead8161160b565b5b92915050565b600060208284031215610ec75760006000fd5b6000610ed584828501610e88565b9150505b92915050565b6000600060408385031215610ef45760006000fd5b6000610f0285828601610e88565b9250506020610f1385828601610e88565b9150505b9250929050565b60006000600060608486031215610f355760006000fd5b6000610f4386828701610e88565b9350506020610f5486828701610e88565b9250506040610f6586828701610e9e565b9150505b9250925092565b6000600060408385031215610f855760006000fd5b6000610f9385828601610e88565b9250506020610fa485828601610e9e565b9150505b9250929050565b610fb8816112eb565b82525b5050565b6000610fca8261122e565b610fd4818561123a565b9350610fe4818560208601611332565b610fed816113fe565b84019150505b92915050565b600061100660238361123a565b915061101182611410565b6040820190505b919050565b600061102a60228361123a565b915061103582611460565b6040820190505b919050565b600061104e60288361123a565b9150611059826114b0565b6040820190505b919050565b600061107260258361123a565b915061107d82611500565b6040820190505b919050565b600061109660248361123a565b91506110a182611550565b6040820190505b919050565b60006110ba60258361123a565b91506110c5826115a0565b6040820190505b919050565b6110da81611319565b82525b5050565b6110ea81611324565b82525b5050565b60006020820190506111066000830184610faf565b5b92915050565b600060208201905081810360008301526111278184610fbf565b90505b92915050565b6000602082019050818103600083015261114981610ff9565b90505b919050565b6000602082019050818103600083015261116a8161101d565b90505b919050565b6000602082019050818103600083015261118b81611041565b90505b919050565b600060208201905081810360008301526111ac81611065565b90505b919050565b600060208201905081810360008301526111cd81611089565b90505b919050565b600060208201905081810360008301526111ee816110ad565b90505b919050565b600060208201905061120b60008301846110d1565b5b92915050565b600060208201905061122760008301846110e1565b5b92915050565b6000815190505b919050565b60008282526020820190505b92915050565b600061125782611319565b915061126283611319565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156112975761129661139c565b5b82820190505b92915050565b60006112ae82611319565b91506112b983611319565b9250828210156112cc576112cb61139c565b5b82820390505b92915050565b60006112e3826112f8565b90505b919050565b600081151590505b919050565b600073ffffffffffffffffffffffffffffffffffffffff821690505b919050565b60008190505b919050565b600060ff821690505b919050565b60005b838110156113515780820151818401525b602081019050611335565b83811115611360576000848401525b505b505050565b60006002820490506001821680151561138157607f821691505b60208210811415611395576113946113cd565b5b505b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b565b6000601f19601f83011690505b919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f657373000000000000000000000000000000000000000000000000000000000060208201525b50565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f737300000000000000000000000000000000000000000000000000000000000060208201525b50565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060208201525b50565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f647265737300000000000000000000000000000000000000000000000000000060208201525b50565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f726573730000000000000000000000000000000000000000000000000000000060208201525b50565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f00000000000000000000000000000000000000000000000000000060208201525b50565b6115f9816112d8565b811415156116075760006000fd5b5b50565b61161481611319565b811415156116225760006000fd5b5b50565bfea264697066735822122021c1229631af5dbc7782b663959606bf3c3af27ac11a4335e8973cda85b3600064736f6c63430008020033 \ No newline at end of file diff --git a/solidity/erc20/SudtERC20Proxy.sol b/solidity/erc20/SudtERC20Proxy.sol deleted file mode 100644 index 32a0cb8f..00000000 --- a/solidity/erc20/SudtERC20Proxy.sol +++ /dev/null @@ -1,383 +0,0 @@ -/* NOTE The base code is copy from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/c789941d76dd713333bdeafe5b4484f6d9543c4e/contracts/token/ERC20/ERC20.sol */ - -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/* - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 - return msg.data; - } -} - -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address recipient, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); - - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); -} - -/** - * @dev Implementation of the {IERC20} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * For a generic mechanism see {ERC20PresetMinterPauser}. - * - * TIP: For a detailed writeup see our guide - * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How - * to implement supply mechanisms]. - * - * We have followed general OpenZeppelin guidelines: functions revert instead - * of returning `false` on failure. This behavior is nonetheless conventional - * and does not conflict with the expectations of ERC20 applications. - * - * Additionally, an {Approval} event is emitted on calls to {transferFrom}. - * This allows applications to reconstruct the allowance for all accounts just - * by listening to said events. Other implementations of the EIP may not emit - * these events, as it isn't required by the specification. - * - * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} - * functions have been added to mitigate the well-known issues around setting - * allowances. See {IERC20-approve}. - */ -contract ERC20 is Context, IERC20 { - /* mapping (address => uint256) private _balances; */ - - mapping (address => mapping (address => uint256)) private _allowances; - - uint256 private _totalSupply; - uint256 private _sudtId; - - string private _name; - string private _symbol; - - /** - * @dev Sets the values for {name} and {symbol}. - * - * The defaut value of {decimals} is 18. To select a different value for - * {decimals} you should overload it. - * - * All three of these values are immutable: they can only be set once during - * construction. - */ - constructor (string memory name_, string memory symbol_, uint256 totalSupply_, uint256 sudtId_) { - _name = name_; - _symbol = symbol_; - _totalSupply = totalSupply_; - _sudtId = sudtId_; - } - - - /** - * @dev Returns the sudt id of the token. - */ - function sudtId() public view virtual returns (uint256) { - return _sudtId; - } - - /** - * @dev Returns the name of the token. - */ - function name() public view virtual returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view virtual returns (string memory) { - return _symbol; - } - - /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5,05` (`505 / 10 ** 2`). - * - * Tokens usually opt for a value of 18, imitating the relationship between - * Ether and Wei. This is the value {ERC20} uses, unless this function is - * overloaded; - * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. - */ - function decimals() public view virtual returns (uint8) { - return 18; - } - - /** - * @dev See {IERC20-totalSupply}. - */ - function totalSupply() public view virtual override returns (uint256) { - return _totalSupply; - } - - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public virtual override returns (uint256) { - uint256[2] memory input; - input[0] = _sudtId; - input[1] = uint256(uint160(address(account))); - uint256[1] memory output; - /* balance_of_any_sudt */ - assembly { - if iszero(call(not(0), 0xf0, 0x0, input, 0x40, output, 0x20)) { - revert(0x0, 0x0) - } - } - return output[0]; - } - - /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `recipient` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address recipient, uint256 amount) public virtual override returns (bool) { - _transfer(_msgSender(), recipient, amount); - return true; - } - - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) public virtual override returns (uint256) { - return _allowances[owner][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { - _approve(_msgSender(), spender, amount); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}. - * - * Requirements: - * - * - `sender` and `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. - * - the caller must have allowance for ``sender``'s tokens of at least - * `amount`. - */ - function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { - _transfer(sender, recipient, amount); - - uint256 currentAllowance = _allowances[sender][_msgSender()]; - require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); - _approve(sender, _msgSender(), currentAllowance - amount); - - return true; - } - - /** - * @dev Atomically increases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); - return true; - } - - /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least - * `subtractedValue`. - */ - function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { - uint256 currentAllowance = _allowances[_msgSender()][spender]; - require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); - _approve(_msgSender(), spender, currentAllowance - subtractedValue); - - return true; - } - - /** - * @dev Moves tokens `amount` from `sender` to `recipient`. - * - * This is internal function is equivalent to {transfer}, and can be used to - * e.g. implement automatic token fees, slashing mechanisms, etc. - * - * Emits a {Transfer} event. - * - * Requirements: - * - * - `sender` cannot be the zero address. - * - `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. - */ - function _transfer(address sender, address recipient, uint256 amount) internal virtual { - require(sender != address(0), "ERC20: transfer from the zero address"); - require(recipient != address(0), "ERC20: transfer to the zero address"); - - _beforeTokenTransfer(_msgSender(), recipient, amount); - - uint256[4] memory input; - input[0] = _sudtId; - input[1] = uint256(uint160(address(sender))); - input[2] = uint256(uint160(address(recipient))); - input[3] = amount; - uint256[1] memory output; - /* transfer_to_any_sudt */ - assembly { - if iszero(call(not(0), 0xf1, 0x0, input, 0x80, output, 0x20)) { - revert(0x0, 0x0) - } - } - - emit Transfer(sender, recipient, amount); - } - - /** - * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. - * - * This internal function is equivalent to `approve`, and can be used to - * e.g. set automatic allowances for certain subsystems, etc. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. - */ - function _approve(address owner, address spender, uint256 amount) internal virtual { - require(owner != address(0), "ERC20: approve from the zero address"); - require(spender != address(0), "ERC20: approve to the zero address"); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } -} diff --git a/solidity/erc20/SudtERC20Proxy.abi b/solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.abi similarity index 81% rename from solidity/erc20/SudtERC20Proxy.abi rename to solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.abi index b19427a3..ac352674 100644 --- a/solidity/erc20/SudtERC20Proxy.abi +++ b/solidity/erc20/SudtERC20Proxy_UserDefinedDecimals.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"totalSupply_","type":"uint256"},{"internalType":"uint256","name":"sudtId_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sudtId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"totalSupply_","type":"uint256"},{"internalType":"uint256","name":"sudtId_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sudtId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]