diff --git a/OEPS/OEP-9.mediawiki b/OEPS/OEP-9.mediawiki new file mode 100644 index 0000000..2ff5f39 --- /dev/null +++ b/OEPS/OEP-9.mediawiki @@ -0,0 +1,452 @@ +
+  OEP: 9
+  Title: Ontology X-shard Asset Contract
+  Author: qiluge 
+  Type: Standard
+  Status: Draft
+  Created: 2019-04-15
+
+ +==Abstract== + +Sharding is the most effective technology to improve the performance of block chains, without violating the premise of decentralization. At sharding environment, asset should be free to transfer across shard. However, the current OEP-4, OEP-5, OEP-8 asset couldn't support asset transfer cross shard. +It is necessary to proposal a new specification to support asset transfer cross shard. This is OEP-9, the X-Shard Asset Contract. + +The OEP-9 only support OEP-4 asset transfer cross shard at now. + +==Motivation== + +While ontology enable sharding, the original OEP-4, OEP-5 and OEP-8 asset cannot transfer cross shard. The OEP-9 is standard interface to implement xshard asset by smart contract. + +==Specification== + +1. To prevent malicious shard, the asset is only allowed to be transferred between root shard and child shard. + +Root shard record the asset supply of each child shard at self ledger, but child shard doesn't know the supply of sibling shard and root shard. + +2. The xshard transfer would return a big integer(called transferId) to identify this xshard transfer. If transfer failed, user can retry transfer by using this transferId. + +Ontology shard communicate by p2p net, so the xshard transfer maybe failed. So, it is necessary to add retry mechanism. User could query asset balance at transfer destination shard after xshard transfer, if user haven't received, retry xshard transfer. + +3. Ontology bottom service would provide basic xshard transfer function in the form of native contract. The name of this native contract is xshard-asset, and the contract hash is 0x0900000000000000000000000000000000000000. + +The core of xshard-asset is control asset supply and user balance at each shard, such as burn asset at shard A and mint asset at shard B while user xshard transfer from shard A to shard B. + +User extend OEP-4 contract to call the xshard-asset contract to implement the asset xshard transfer. + +4. XShard-asset contract has already provide check witness while invoking function that would change user balance and asset supply, except the mint interface. Also the contract author could check witness at his neovm contract. + +5. The OEP-9 contract only can be deployed at root shard, and must be initialized meta data and register to xshard-asset contract before invoked any function. + +After initialized meta data, the contract can be invoked at each shard. And after register to xshard-asset contract, the contract own a assetId at ontology sharding network. + +===Methods=== + +====init==== + +
+public static void init()
+
+ +Init contract meta data firstly, then register this asset to xshard-asset contract. + +Only can be invoked at root shard. + +====name==== + +
+public static string name()
+
+ +Returns the name of the token - e.g. "MyToken". + +Only can be invoked at root shard. + +====symbol==== + +
+public static string symbol()
+
+ +Returns a short string symbol of the token - e.g. "MYT". + +Only can be invoked at root shard. + +This symbol SHOULD be short (3-8 characters is recommended), with no whitespace characters or new-lines and SHOULD be limited to the uppercase latin alphabet (i.e. the 26 letters used in English). + +====decimals==== + +
+public static byte decimals()
+
+ +Returns the number of decimals used by the token - e.g. 8, means to divide the token amount by 100,000,000 to get its user representation. + +====totalSupply==== +
+public static BigInteger totalSupply()
+
+Invoke xshard-asset contract interface 'oep4TotalSupply' at root shard, returns the total number of token in root shard. + +If invoking at other shard, there are no value return. + +====shardSupply==== +
+public static BigInteger shardSupply(BigInteger shardId)
+
+ +Invoke xshard-asset contract interface 'oep4ShardSupply', returns the total number of token at shard shardId. + +The parameter shardId SHOULD be a uint64 integer. + +Only can be invoked at root shard. + +====wholeSupply==== +
+public static BigInteger wholeSupply()
+
+ +Invoke xshard-asset contract interface 'oep4WholeSupply', returns the total number of token at all shard. + +Only can be invoked at root shard. + +====supplyInfo==== +
+public static String supplyInfo()
+
+ +Invoke xshard-asset contract interface 'oep4SupplyInfo', returns the supply info of each shard. The return value is map JSON format string. The map key is shardId and value is string of shard supply. + +Only can be invoked at root shard. + +====balanceOf==== + +
+public static BigInteger balanceOf(byte[] address)
+
+ +Invoke xshard-asset contract interface 'oep4BalanceOf', returns the token balance of the address. + +If invoked at non-root shard, the shard must receive a xshard transfer before. Otherwise the function will throw an exception. + +The parameter address SHOULD be a 20-byte address. If not, this method SHOULD throw an exception. + +====assetId==== +
+public static BigInteger assetId()
+
+ +Invoke xshard-asset contract interface 'oep4AssetId', returns the assetId, the identification of this asset. + +If invoked at non-root shard, the shard must receive a xshard transfer before. Otherwise the function will throw an exception. + +====transfer==== + +
+public static bool transfer(byte[] from, byte[] to, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4Transfer', transfers an amount of tokens from the from account to the to account. + +This function transfer asset in the same shard. + +The parameters from and to SHOULD be 20-byte address. If not, this method SHOULD throw an exception. + +The parameter amount is transfer value of token. + +====transferMulti==== +
+public static bool TransferMulti(object[] args)
+
+public struct State
+{
+     public byte[] From;
+     public byte[] To;
+     public BigInteger Amount;
+}
+
+ +Invoke xshard-asset contract interface 'oep4TransferMulti', transfer asset from multi account to multi account at same shard. + +The transferMulti allows transfer amount of token from multiple from to multiple to multiple times. + +The parameter is object array, the object is State struct, which contains three items.From is transfer sender, which SHOULD be 20-byte address.To is transfer receiver, which +also SHOULD be 20-byte address. Amount is transfer value of token. If any of transfer fail, all of the transfers SHOULD be failed, and the method SHOULD throw an exception. + +====approve==== +
+public static bool approve(byte[] owner, byte[] spender, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4Approve'. + +The approve allows spender to withdraw from owner account multiple times, up to the value amount.But the withdraw has been limited at same shard. If this function is called again it overwrites the current allowance with value. + +The parameters ownerand spender SHOULD be 20-byte addresses. If not, this method SHOULD throw an exception. + +====transferFrom==== +
+public static bool transferFrom(byte[] spender, byte[] from, byte[] to, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4TransferFrom'. + +The transferFrom method is used for a withdraw workflow, allowing spender to withdraw amount of token from from account to to account at same shard. + +The parameters spender from and to SHOULD be 20-byte addresses. If not, this method SHOULD throw an exception. + +====allowance==== + +
+public static BigInteger allowance(byte[] owner, byte[] spender)
+
+ +Invoke xshard-asset contract interface 'oep4Allowance', returns the amount which spender is still allowed to withdraw from owner. + +====mint==== + +
+public static bool mint(byte[] user, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4Mint', mint amount asset to user account. The contract should check witness before invoke xshard-asset contract to preventing malicious mint asset. + +The parameters user SHOULD be 20-byte addresses. If not, this method SHOULD throw an exception. + +====burn==== + +
+public static bool burn(byte[] user, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4Burn', burn amount asset from user account. + +The parameters user SHOULD be 20-byte addresses. If not, this method SHOULD throw an exception. + +====xshardTransfer==== + +
+public static BigInteger xshardTransfer(byte[] from, byte[] to, BigInteger toShard, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'oep4XShardTransfer', transfers an amount of tokens from the from account to the to account at shard toShard. + +This function transfer asset cross shard, cannot transfer asset at same shard, cannot transfer asset between non-root shard and non-root shard. + +Returns a big integer identified this xshard transfer. + +The parameters from and to SHOULD be 20-byte address. If not, this method SHOULD throw an exception. + +The parameter toShard is transfer destination shard. + +The parameter amount is transfer value of token. + +====xshardTransferRetry==== + +
+public static bool xshardTransferRetry(byte[] from, BigInteger transferId)
+
+ +Invoke xshard-asset contract interface 'oep4XShardTransferRetry', retry xshard transfer by using transferId. + +If transferId xshard transfer has not existed at invoked shard, this method will throw an exception. + +If transferId xshard transfer has already completed or not at invoked shard, this method will return true. + +The parameter from SHOULD be 20-byte address. If not, this method SHOULD throw an exception. + +The parameter transferId is xshard transfer identification. + +====getXShardTransferDetail==== + +
+public static string getXShardTransferDetail(byte[] user, BigInteger transferId)
+
+ +
+public struct XShardTransfer {
+    public BigInteger Id
+    public BigInteger ToShard
+    public byte[] ToAccount
+    public BigInteger Amount
+    public uint8 Status
+}
+
+ +Invoke xshard-asset contract interface 'getOep4Transfer', returns transferId xshard transfer's detail. + +If transferId xshard transfer has not existed at invoked shard, this method will throw an exception. + +The return value is structure XShardTransfer JSON format string, for example {"id":111,"to_shard":1,"to_account":"AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6","amount":190,"status":6}. If status equals 6, the xshard transfer hasn't completed, it's pending, if status is 7, the transfer has already completed. + +The parameter user SHOULD be 20-byte address. If not, this method SHOULD throw an exception. + +The parameter transferId is xshard transfer identification. + +====getPendingXShardTransfer==== + +
+public static string getPendingXShardTransfer(byte[] user)
+
+ +Invoke xshard-asset contract interface 'getOep4PendingTransfer', returns user all pending xshard transfer at invoked shard. + +The return value is structure XShardTransfer array JSON format string, for example [{"id":111,"to_shard":1,"to_account":"AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6","amount":190,"status":6}]. + +The parameter user SHOULD be 20-byte address. If not, this method SHOULD throw an exception. + +===Supplement=== + +The supplement is how to transfer ong across shard at neovm contract. The ong xshard transfer maybe a important function while using smart contract at sharding environment. + +====xshardTransferOng==== + +
+public static BigInteger xshardTransferOng(byte[] from, byte[] to, BigInteger toShard, BigInteger amount)
+
+ +Invoke xshard-asset contract interface 'ongXShardTransfer', transfers an amount of ong from the from account to the to account at shard toShard. + +This function transfer asset cross shard, cannot transfer asset at same shard, cannot transfer asset between non-root shard and non-root shard. + +The means of parameters and return value is same as xshardTransfer. + +====xshardTransferOngRetry==== + +
+public static bool xshardTransferOngRetry(byte[] from, BigInteger transferId)
+
+ +Invoke xshard-asset contract interface 'ongXShardTransferRetry', retry xshard transfer by using transferId. + +If transferId xshard transfer has not existed at invoked shard, this method will throw an exception. + +If transferId xshard transfer has already completed or not at invoked shard, this method will return true. + +The means of parameters and return value is same as xshardTransferRetry. + +====getOngXShardTransferDetail==== + +Same with getXShardTransferDetail. + +====getOngPendingXShardTransfer==== + +Same with getPendingXShardTransfer. + +===Events=== + +====transfer==== + +
+public static event transfer(BigInteger assetId, byte[] from, byte[] to, BigInteger amount)
+
+ +XShard-asset contract will publish this event while asset transfer at same shard, include init, transfer and transferFrom. + +Fro example: +
+{
+    "transfer",
+    "1",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "10000000"
+}
+
+ +====approval==== +
+public static event approval(BigInteger assetId, byte[] owner, byte[] spender, BigInteger amount)
+
+ +XShard-asset contract will publish this event while approving asset at same shard. + +Fro example: +
+{
+    "approve",
+    "1",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "10000000"
+}
+
+ +====mint==== +
+public static event mint(byte[] user, BigInteger assetId, BigInteger amount)
+
+ +XShard-asset contract will publish this event while mint asset. + +Fro example: +
+{
+    "mint",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "1",
+    "10000000"
+}
+
+ +====burn==== +
+public static event burn(byte[] user, BigInteger assetId, BigInteger amount)
+
+ +XShard-asset contract will publish this event while burn asset. + +Fro example: +
+{
+    "burn",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "1",
+    "10000000"
+}
+
+ +====xshardTransfer==== +
+public static event xshardTransfer(BigInteger assetId, byte[] from, byte[] to, BigInteger amount, BigInteger transferId, BigInteger toShard)
+
+ +At transfer initiation shard, xshard-asset contract will publish this event while xshard transfer successfully. + +Fro example: +
+{
+    "xshardTransfer",
+    "1",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "10000000",
+    "10",
+    "1"
+}
+
+ +====xshardReceive==== +
+public static event xshardReceive(BigInteger assetId, byte[] from, byte[] to, BigInteger amount, BigInteger transferId, BigInteger fromShard)
+
+ +At transfer destination shard, xshard-asset contract will publish this event while received a xshard transfer asset. + +Fro example: +
+{
+    "xshardReceive",
+    "1",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6",
+    "10000000",
+    "10",
+    "1"
+}
+
+ +===Implementation=== +====Example implementations are available at==== + +OEP-9 Python Template: [[https://github.com/qiluge/ontology-xshard-contract/blob/master/xshardassetdemo.py | Python Template]]