NEO改進協議提案(NEP1、NEP2、NEP3、NEP4、NEP5)

買賣虛擬貨幣
NEO改進協議提案1(NEP-1)什麼是NEPNEP是NEO改進協議。一份NEP是一份設計文件用於給給NEO社羣提供資訊,或是描述一個NEO的新特性或其工序或環境。NEP需要對特性提供一份簡要的技術說明以及基本原理。NEP的作者有責任在社羣內構建輿論和編輯不同的觀點NEP基本原理我們計劃NEP的主要作用是提出新特性,收集社羣中關於某個問題的觀點和整理歸納引進到NEO中的設計決定。由於NEP作為版本檔案儲存在版本化的儲存庫中,它們的版本歷史是特性提案的歷史記錄。對於NEO的實施者,NEP是一種便捷的方式來追蹤他們的實施進度。理想情況下,每個實施維護人員都會列出他們的NEP。如此會使終端使用者很方便的瞭解某個實現或者庫的狀態。
NEP型別有三種型別的NEP:·一份標準路線 NEP描述任何會影響多數NEO實施者的影響,例如一個網路協議的改變,一個區塊或者交易有效性規則的改變,擬議應用標準/公約,或者任何會影響應用使用NEO操作性的改變或者新增·一份資訊類 NEP描述一個NEO的設計問題,或提供指給社羣指南或者資訊,但是並不提議一個新特性。資訊類的NEP並不必然代表一個NEO社羣的共識或者推薦,所以使用者或者實施者可以自由的忽略資訊類的NEP或跟隨建議·一份元NEP描述了一個圍繞NEO的工序流程,或者提出了一個工序流程(或事專案)的改變。元NEPS類似於標準路線NEP,但適用於除NEO協議本身之外的區域。他們可能提出一個實現,但不提到NEO的程式碼庫;他們需要社羣的共識;與資訊類NEP不同,它們不僅僅是建議,而且使用者通常不能自由地忽略它們。示例包括流程、指南、決策過程的更改,以及NEO開發中使用的工具或環境的更改。NEP工作流程
一個NEP的流程開始於一個關於NEO的新想法。強烈建議一個單一的NEP包含一個單一的關鍵流程或新想法。多關注NEP就越容易成功。對於單一客戶端的變動不需要一個NEP,但可能影響多客戶端的改變或者定義多個app應用標準則需要。NEP編輯者有權拒絕NEP提案,如果它們顯得過於不集中或過於寬泛。如果有疑問,把你的NEP分成幾個比較集中的。每個NEP必需有個擁護者—使用以下描述的風格和格式編寫NEP的人,在的論壇中適當的指導討論,並試圖圍繞這個想法建立社羣共識。在寫一個NEP前先公開審查一下想法意味著節約了作者的潛在時間。先向NEO社羣詢問一個想法是否具有原創性有助於防止花費太多時間在基於先前討論而保證被否定的事情上(搜尋因特網並不總是奏效)。它也有助於確定這個想法適用於整個社羣,而不僅僅是作者。僅僅因為一個想法對作者來說聽起來不錯,並不意味著它對使用NEO的各領域的大多數人都有效。透過合適的論壇來評估NEP,包括NEO子版、倉庫的問題部分和NEO閒置通道之一。特別的,倉庫的問題部分非常適合與社羣討論你的提議並開始建立一些有有關於你的NEP的正式言論。一旦擁護者向近NEO社羣詢問一個想法是否有任何機會被接納為NEP草案這給了作者一個連續編輯NEP草稿的機會,用於正確的格式和質量。這也允許進一步的公眾評論和NEP的作者來關注這個提案。如果NEP的協作者同意,NEP編輯者會給NEP分配一個數字,標記它是標準、資訊、或是元,並給它狀態‘草案’,並將它加入到git倉庫。NEP編輯者不會不合理的否定一個NEP。否定NEP的理由包括重複勞動、技術不健全、不正當動機或向後相容,或違背NEO的價值觀標準追蹤型NEP由三部分組成,設計文件、實現,最後如果需要更新的正式規範。在實施開始之前,NEP需要被稽覈和採納,除非該實施將有助於人們研究NEP。標準追蹤型NEP必須包含一個實現——以程式碼、補丁或URL的形式——在其被認定結束狀態前。
對於一個被接受的NEP,它必須滿足一定的最低標準。所提出的改善提案必須是一個清晰和完整的描述。改善必須是一個純的改進。提案實現,如果適用的話,必須是可靠的並且不能過分複雜化協議。一旦NEP被採納,就必須完成實現。當實現完成並被社羣採納時,狀態將改為“結束”。NEP也可以被賦予“延期”的狀態。NEP作者或編輯者可以在NEP沒有進展的情況下給NEP分配該狀態。一旦NEP被推遲,NEP編輯者可以重新將其分配成草稿狀態。NEP也可以被“拒絕”。也許這不是個好主意。記錄這一事實仍然很重要。NEP也可以被一個不同的NEP替代,使原來的過期。

NEP狀況的可能路徑如下:

一些資訊型或元NEP也可能是狀態“活躍”如果他們從未被完成,例如NEP1(本NEP)。


怎麼才是一個合格的NEP


每個NEP應該有以下部分:


·序言——RFC 822樣式標頭,包含關於NEP的後設資料,包括NEP編號、簡短的描述性標題(限制最多44個字元)、姓名、以及可選的每個作者的聯絡人資訊等。
·摘要——-一個簡短的(200字)描述正在處理的技術問題。
·動機(*可選)-動機是那些想要改變NEO協議的NEP至關重要的部分。它應該清楚地解釋現有的協議規範的不足以及NEP解決的問題。沒有充分動機的NEP提案可能被徹底拒絕。


·詳述——技術詳述應該描述新特徵的語法和語義。該規範應該足夠詳細,以允許針對任何當前NEO平臺的競爭、可互操作的實現。
•基本原理——基本原理詳細說明設計目的以及設計方案的理由。它應該描述相關工作的替代設計,例如在其他語言中如何支援該特性。基本原理也可以提供社羣內共同意見的證據,並且應當討論在討論期間提出的重要反對或重點。
·向後相容性——引入向後相容性的所有NEP必須包括描述其不相容性及其嚴重性。NEP必須解釋作者是如何處理這些不相容性的。沒有足夠的向後相容性的NEP提交可能被徹底拒絕。
·測試用例——實現的測試用例對於那些會引起共識改變的NEP是必須的。其他NEP可以選擇包括測試用例的連結如果需要的化。
·實現——實現必須在任何NEP“完結”狀態前之前完成,但是不需要在NEP受理前完成。最好先完成規範和原理並在編寫程式碼之前達成共識。


NEP格式和模板
NEP必需用 mediawiki or markdown格式編寫。圖片檔案必需包含在NEP的子目錄。


NEP序言


每個NEP必須由一個RFC822格式的頭部欄開始。頭部欄必須包含以下順序。
用*號標示的是可選的,稍後寫介紹。其他都是必須的。
NEP: <NEP編號>(由NEP編輯者決定)
Title: <NEP標題>
Author: <list of authors’ real names and optionally, email address>
*Discussions-To: <email地址>
Status: <Draft | Active | Accepted | Deferred | Rejected | Withdrawn |
Final | Superseded>
Type: <Standard | Informational | Meta>
Created: <date created on, in ISO 8601 (yyyy-mm-dd) format>
*Replaces: <NEP編號>
*Superseded-By: <NEP編號>
*Resolution:
作者頭部欄列出NEP的所有作者/所有者的姓名,以及可選的電子郵件地址。作者頭值的格式必須是 Random J. User admin@chaindaily有email地址的情況下,Random J. User 沒有email地址的情況下。
如果有多個作者,每一個都應在之後獨立的一行中的遵守RFC2822的協議。
注意:解決方案欄只適用於標準追蹤型NEP。它包含一個URL,該URL應該指向一個電子郵件訊息或其他關於NEP的宣告的Web資源。
當NEP處於私下討論階段時(通常在初始草稿階段),Discussions-To欄將指示正在討論NEP的郵件列表或URL。如果NEP處於與作者私下討論階段,則不需Discussions-To欄。


型別欄指定NEP的型別:標準、資訊或元。


建立欄記錄了NEP被分配編號的日期。它應該是YYYY-MM-DD格式,例如2001-08-14。


NEPS可能有一個需求欄,指示NEP依賴的NEP編號。


NEP還可以有一個Superseded-By欄,指示NEP已經被後面的文件淘汰;該值是替換當前文件的NEP文件編號。較新的NEP必須有一個替換欄,該欄包含其過時的NEP編號。


附件


NEP可以包括附件,如圖表。此類檔案必須包含在該NEP的子目錄中,並命名為nep-x-y.ext,其中“x”是NEP編號,“y”是序列號(從1開始),而“ext”被實際的副檔名(例如“png”)替換。


NEP所有權轉讓


有時候需要將NEP所有權轉讓給新的擁護者。一般來說,我們希望保留原作者作為已轉移NEP的合著者,但這取決於原作者。轉移所有權的一個恰當的理由是,因為原始作者不再有時間或興趣更新它,或者繼續執行NEP的流程,或者已經脫離“網路”的位面(即,無法訪問或不回覆電子郵件)。轉移所有權的一個不恰當的原因是因為你不同意NEP的方向。我們試圖在圍繞NEP建立共識,但如果這是不可能的,你可以提交一個競爭的NEP。


如果您有興趣接管NEP的所有權,請向原始作者和NEP編輯者傳送請求接管的訊息。如果原作者沒有及時回覆郵件,NEP編輯者會做出單方面的決定(此類決定並非不能逆轉:).


NEP編輯者


當前的NEP編輯者是·Erik Zhang (@erikzhang)
NEP編輯者的職責和工作流程
每收到一份新的NEP,編輯者會做如下事情:
·閱讀NEP檢查它是否完備:健全和完整。想法必需有技術意義,即使它看起來並不能被接受。
·標題必需準確的描述內容。
·編輯NEP的語言(拼寫,語法,句子結構等),標記,程式碼風格。
如果NEP並不完備,編輯者會將其退回給作者重新修訂,並給出具體說明,一旦NEP準備好合到倉庫,NEP編輯者會:
·分配一個NEP編號(基本是下一個可用的數字,但有時也可能是一個特殊數字,例如666或者3141)在拉取請求的評論中.
·當作者準備好後合併下拉請求(允許有進一步的同行評審時間).
·在README.mediawiki中列出NEP.
·回覆NEP作者告知下一步操作.
NEP編輯者旨在履行管理和編輯的職責.NEP編輯者收集NEP的變化,並改正任何我們看到的結構、語法、拼寫或標記上的額錯誤。


歷史


本文件是根據Amir Taaki從Python版PEP-0001衍生出的比特幣的BIP-0001文件編寫的。在許多地方僅是簡單複製和修改。雖然PEP-0001文件是由Barry Warsaw, Jeremy Hylton, and David Goodger編寫,但是他們並不負責其在NEO改善過程中的使用,並且不用回答任何NEO或者NEP的技術問題。請把所有意見評論直接提交給NEP編輯者。


NEO改進協議提案2(NEP-2)

摘要


提出了一種以58字元 Base58Check編碼的可列印字串的形式對密碼保密型私鑰記錄進行加密和編碼的方法。加密私鑰記錄旨在用於紙質錢包。每一個記錄字串都包含除了密碼之外重構私鑰所需的所有資訊,並且該方法使用加鹽和scrypt來抵抗暴力攻擊。


動機


密碼和密碼保護型金鑰是個人間傳送資產的新實踐。想要傳送資產的人可以透過郵政郵件郵寄一個受密碼保護的紙錢包並透過電話或者email給接收者密碼,以保證傳遞的安全不受其他通道的攔截。紙錢包的使用者可以攜帶資金的加密私鑰並在家中留存一份複製以預防意外的遺失和偷竊。把資產存在銀行賬戶或者保險箱中的紙錢包的使用者可以把密碼留在家裡或者與可信的夥伴分享已預防銀行中的某人乘機訪問紙錢包並花費其中的資產。預見和不可預見的關於密碼保護型私鑰的用例還有很多。 另一方面,標準的密碼保護型私鑰格式使得其能夠共享來自不同錢包客戶端的私鑰。


基本原理


用例:作為一個NEO紙錢包使用者,我喜歡新增加密的功能,如此我的NEO紙錢包可以拆解成兩個因子:我有的和我知道的。 用例:作為一個NEO使用者想要用一個私鑰向個人或者公司付款,我不必擔心任何通訊渠道會攔截我的key和導致資產的被盜。我想要提供一個密碼保護型金鑰,伴隨一個可以透過其他渠道傳輸的密碼。


詳述


本提議運用到了以下函式和定義: ·AES256加密、AES256解密,是眾所周知的AES分組編碼不考慮初始向量和塊連線的簡單格式。這些函式每一個都需要一個256位的key和16位元組的輸入和確定的16位元組的輸出。 ·SHA256,一種眾所周知的任意位元組長度輸入和固定產出32位元組長度hash的雜湊演算法。 ·scrypt,一個著名的金鑰推導演算法。它需要以下引數(string) password, (string) salt, (int) n, (int) r, (int) p, (int) length,並固定產生一個長度等於length長度的位元組陣列。 Base58Check,一個在NEO系統中廣泛使用的用58的字元byte[]編碼的方法。


字首


建議將Base58Check編碼過後的字串以6字開頭。數字6旨在從使用者的角度表示一種需要其他東西才能生效的私鑰–總的定義可以理解為將來包括特別是在多籤交易中的金鑰,並且被選遵從現有字首5,多見於WIF格式表示一種非加密私鑰。 建議第二個字元應該給出提示所需什麼因子,對於加密金鑰需要一個密碼,建議使用大寫字母P。 為保持加密金鑰的大小,在AES加密中不使用初始向量(IVS)。相反,使用scrypt從密碼以及NEO地址的32位hash作為鹽匯出用於類似初始向量用途的合適值。


建議詳述


物件識別符號字首:0x0142。這是在Base58Check編碼記錄開頭的常量位元組,它們的存在導致結果字串具有可預見的字首。 使用者如何判斷:58個字元總是以“6P”開頭 有效載荷位元組數(不包括字首):37 ·1位元組(FLAG位元組):始終為0xE0 ·4位元組:Sha256(Sha256(expected_neo_address))[0…3]),用於拼寫檢查和加鹽。 16位元組:AES加密金鑰材料記錄(加密半數1) 16位元組:AES加密金鑰材料記錄(加密半數2) 在BASE58CHECK編碼(字首6Py)中的範圍: 最小值:

6PYJXKPVNKXUZAFD2B5ZSZAFJYNP4EZQQECJS39 449 QUUXLNXJLX6LG(基於01 42 E0加三十六個00) 最大值:6PyxG5TnGyLyxDrZiqxBuxxdotBNTBI3D61MQBXPPZQZEJTVQQHSCNK(基於01 42 E0加三十六個FF)


加密步驟


1、計算NEO地址(ASCII), 並獲取SHA256(SHA256())的前四個位元組.我們將其叫做地址雜湊。 2.使用Scrypt從密碼匯出一個金鑰。 ·引數:密碼是以UTF-8格式的密碼。鹽採用之前得到的地址hash,n=16384,r=8,p=8,length=64 ·把結果的64位元組分成2半,稱他們為匯出半數1和匯出半數2. 3.做AES256加密(block = privkey[0…15] xor derivedhalf1[0…15], key = derivedhalf2),把16位元組的結果叫做加密半數1. 4.做AES256加密(block = privkey[16…31] xor derivedhalf1[16…31], key = derivedhalf2),把16位元組的結果叫做加密半數2. 加密私鑰是以下Base58Check編碼下的串聯,總共39位元組,沒有Base58 checksum: ·0x01 0x42 + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2


解密步驟


1.從使用者那獲取加密私鑰和密碼。 2.把密碼和地址hash帶入Scrypt函式得到半匯出數1和半匯出數2. 3.用AES256Decrypt解密半匯出數1和半匯出數2,併合並兩部分並將結果和半匯出數1做異或得到明文形式私鑰。 4.把明文私鑰轉化成NEO地址。 5.求NEO地址hash,並驗證加密私鑰記錄中的地址hash是否與之匹配。如果不是,則報告密碼錯誤。


向後相容性


向後相容性是最小的,由於它是一種新標準幾乎擴充套件了WIF格式。假設私鑰資料的入口可以接受現存格式的私鑰(比如16進位制數或者WIF格式);本草案使用的金鑰格式不能被錯誤地用於任何現有的格式,並保留自動檢測能力。


測試用例


Test 1: • Passphrase: TestingOneTwoThree • Encrypted: 6PYVPVe1fQznphjbUxXP9KZJqPMVnVwCx5s5pr5axRJ8uHkMtZg97eT5kL • Unencrypted (WIF): L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP • Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5 Test 2: • Passphrase: Satoshi • Encrypted: 6PYN6mjwYfjPUuYT3Exajvx25UddFVLpCw4bMsmtLdnKwZ9t1Mi3CfKe8S • Unencrypted (WIF): KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7 • Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE


實現


• neo-project/neo: https://github.com/neo-project/neo/blob/master/neo/Wallets/KeyPair.cs#L75 • CityOfZion/neon-js: https://github.com/CityOfZion/neon-js/blob/master/src/wallet/nep2.js


NEO改進協議提案3(NEP-3)

摘要
應用程式二進位制介面(ABI)是兩個程式模組之間的介面,其中一個通常是庫和/或作業系統,另一個通常是由程式設計師建立的應用程式。


本NEP描述了NEO智慧合約的ABI標準


動機


NEO智慧合約系統旨在在合同之間相互呼叫。為實現這一目標,我們需要一種機制來公開智慧合約的介面。使用NeoContract ABI,開發人員可以輕鬆的建立程式來呼叫智慧合約或編寫能自動訪問合同功能的客戶端。


原理


我們假設應用程式二進位制介面(ABI)是強型別的,在編譯時已知且靜態。其不會提供內省機制。我們主張所有合同都具有其在編譯時可以呼叫的合約的介面定義
此詳述不涉及其介面是動態的或僅在執行時可知的合約。如果這些案例十分重要,可以適當的提出作為特殊構建在NEO的生態體系中。


詳述


合約
NeoContract ABI以Json格式定義定義,包含以下結構體,並且某些頂層物件可以包含數個子物件:
{
“hash”: “0x562851057d8afbc08fabc8c438d7cc771aef2195”,
“entrypoint”: “main”,
“functions”: [],
“events”: []
}
hash是合約的指令碼雜湊。它採用16進位制字元按大端序編碼
Entrypoint 代表合約函式的入口
functions 是一個函式物件陣列,用於描述合約中每個函式的細節
events 是一個事件物件陣列,用於描述合約中沒給事件的細節


Function


函式物件包含以下結構:
{
“name”: “transfer”,
“parameters”: [],
“returntype”: “Boolean”
}
name代表函式的名稱,可以是任何有效的識別符號。
parameters是一個引數物件陣列,用於描述函式中每個引數的詳細資訊
returntype代表函式的返回型別。可以是以下任意一種值:Signature, Boolean, Integer, Hash260, Hash256, ByteArray, PublicKey, String, Array, InteropInterface


Event


事件物件包含以下結構體
{
“name”: “refund”,
“parameters”: []
}
name代表事件的名稱,可以是任何有效的識別符號。
parameters是一個引數物件陣列,用於描述事件中每個引數的詳細資訊


Parameter


引數物件包含以下結構體:
{
“name”: “from”,
“type”: “Hash260”
}
name代表引數的名稱,可以是任意有效字元
type代表引數型別。可以是以下任意一種值:Signature, Boolean, Integer, Hash260, Hash256, ByteArray, PublicKey, String, Array, InteropInterface


ParameterType


引數型別有以下值:
名稱 描述
Signature A signature of a transaction or block which is generated by the user.
Boolean 布林值的值是true或者false.
Integer An arbitrarily large integer whose value in theory has no upper or lower bounds.
Hash260 160位元的整型.
Hash256 256位元的整型.
ByteArray 位元組陣列.
PublicKey 採用壓縮模式的ECC公鑰.
String 採用UTF-8編碼的字串.
Array 物件陣列. 其元素型別可以是引數型別中的任何一種.
InteropInterface 返回互操作服務的介面.
Void Void 意味著函式沒有返回值. 該值不是引數型別中的任何一種.


EntryPoint


強烈建議每個合約具有以下入口函式:
{
“name”: “main”,
“parameters”: [
{
“name”: “operation”,
“type”: “String”
},
{
“name”: “args”,
“type”: “Array”
}
],
“returntype”: “ByteArray”
}
透過這種方式,呼叫者可以從入口點輕鬆的訪問函式,透過第一個引數指定呼叫函式的名稱,透過第二個引數指定函式的的引數


NEO改進協議提案4(NEP-4)

摘要


此NEP提案概述了一種機制,透過該機制,智慧合約能夠呼叫直到執行時才知道的其他智慧合約,而不僅限於呼叫在編譯時定義的智慧合約。為了保持智慧合約與未來動態分片過程介面的能力,包括一份用於構建智慧合約的提案詳述會表示智慧合約是否需要動態合約呼叫功能。


動機


此NEP的動機是為讓智慧合約(SC)的的作者能夠為編譯時不可知的SC提供介面。例如,操作NEP-5 token的分散交換的SC可以呼叫在執行時才確定的token的SC的transferFrom方法。目前,這樣的SC需要對所有支援的NEP-5 token地址進行硬編碼,並在新增新token時重新發布。以太坊上的許多SC都需要此功能,包括任何符合ERC223 token標準的功能。透過讓SC作者能夠在執行時指定SC與之互動,類似於更先進的以太坊合約中包含的功能將更容易開發和維護。


值得注意的是,向NEO新增動態SC呼叫會影響可伸縮性。透過動態SC呼叫,我們不用再事先知道將呼叫哪些其他SC,因此VM狀態的子集必須可用於執行才能成功。這使得動態分片更難實現。


為了克服可擴充套件性的缺點,該提議在區塊鏈上建立時為每個SC新增一個設定,以表示它是否需要動態呼叫功能。該設定將允許所有現存的合約和大多數未來合約在預先已知的儲存上下文中執行,因此更適合於動態分片,同時還使SC更強大和更具表現力。


考慮到動態呼叫功能的可擴充套件性缺陷,該NEP建議了一個需要此功能的SC的更新費用結構。下面列出了更新費用結構的樣例實現。


詳述


該提案概述了Neo專案的三個部分的變更,並提供瞭如何在SC中使用此變更的示例:


•neo
•neo-vm
•neo編譯器
•智慧合約例項


下面列出的變更並非試圖詳盡無遺,而是概述每個庫中所需的重要變更。


neo


為了讓一份SC表示其是否能夠動態呼叫其他SC,該NEP建議在neo.Core.ContractState物件中新增以下屬性,且預設值為false
public bool HasDynamicInvoke
HasDynamicInvoke屬性
為了使實現與當前的Neo協議保持互操作,HasDynamicInvoke屬性將被序列化為位元組標誌跟在現有的HasStorage屬性之後:

[Flags]
    public enum ContractPropertyState : byte
    {
        NoProperty = 0,
        HasStorage = 1 << 0,
        HasDynamicInvoke = 1 << 1,
    }
public class ContractState : StateBase, ICloneable<ContractState>
    {
...
public ContractPropertyState ContractProperties;
public bool HasStorage => ContractProperties.HasFlag(ContractPropertyState.HasStorage)
public bool HasDynamicInvoke => ContractProperties.HasFlag(ContractPropertyState.HasDynamicInvoke)
…

public override void Serialize(BinaryWriter writer)
        {
            base.Serialize(writer);
            writer.WriteVarBytes(Script);
            writer.WriteVarBytes(ParameterList.Cast<byte>().ToArray());
            writer.Write((byte)ReturnType);
            writer.Write(ContractProperties);   // currently is writer.Write(HasStorage)
            writer.WriteVarString(Name);
            writer.WriteVarString(CodeVersion);
            writer.WriteVarString(Author);
            writer.WriteVarString(Email);
            writer.WriteVarString(Description);
        }

以下在neo.SmartContract.ApplicationEngine中的變更用於計量合約建立不同的Gas費用。沒有額外附加功能的合約建立費用會被降低,而那些HasDynamicInvoke或HasStorage屬性為true的合約建立會產生額外的費用。
        protected virtual long GetPriceForSysCall()
        {
           // lines omitted
           ... case"Neo.Contract.Create": case"Neo.Contract.Migrate": case"AntShares.Contract.Create": case"AntShares.Contract.Migrate":
                    
                    long fee = 100L;
                    ContractState contract = PeekContractState() // this would need to be implemented if( contract.HasStorage ) 
                    {
                      fee += 400L
                    } if( contract.HasDynamicInvoke ) 
                    {
                      fee += 500L;
                    } return fee * 100000000L / ratio;
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253複製程式碼


neo-vm


本詳細提案給NEO虛擬機器新增了一個新OpCode,代表相對於靜態的動態AppCall的使用
DYNAMICCALL = 0xFA
DYNAMICCALL OpCode 在neo.VM.ExecutionEngine.ExecuteOp 方法的執行也按照以下方式不同於現有的APPCALL和TAILCALL OpCodes

 case OpCode.APPCALL:
                case OpCode.TAILCALL:
                case OpCode.DYNAMICCALL:
                    {
                        if (table == null)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
byte[] script_hash = null;
if ( opcode == OpCode.DYNAMICCALL ) 
                        {
script_hash = EvaluationStack.Pop().GetByteArray();

                            if ( script_hash.Length != 20 ) 
                            {
                              State |= VMState.FAULT
                              return;
                            }
} else {
script_hash = context.OpReader.ReadBytes(20);
                        }
byte[] script = table.GetScript(script_hash);
                        if (script == null)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        if (opcode == OpCode.TAILCALL || opcode == OpCode.DYNAMICCALL)
                            InvocationStack.Pop().Dispose();
                        LoadScript(script);
                    }
                    break;
123456789101112131415161718192021222324252627282930313233複製程式碼

neo編譯器
將方法呼叫轉換為DYNAMICCALL的示例方法如下:

else if (calltype == CallType.DYNAMICCALL)
            {
                _ConvertPush(callhash, null, to)
                _Convert1by1(VM.OpCode.DYNAMICCALL, null, to);
}
12345複製程式碼


智慧合約示例
以下是一個SC演示了所提案功能的簡單使用

using Neo.SmartContract.Framework.Services.Neo;
namespace Neo.SmartContract
{
    public class DynamicTotalSupply : Framework.SmartContract
    {
        public static int Main(byte[] contract_hash)
        {

            if( contract_hash.Length == 20 ) {

                BigInteger totalSupply = DynamicCall( contract_hash, 'totalSupply')

                return totalSupply;
            }

            return 0;
        }
    }
}
12345678910111213141516171819複製程式碼


原理


用動態SC呼叫來動態分片(以太坊已經提出了許多解決方案)並不是不可能的,儘管這會增添已經很困難的任務。
僅僅因為我們事先知道計算呼叫圖並不意味著我們能夠成功地完美分配資源,沒有重疊的子集。仍然可能需要實現分片之間的通訊,如以太坊提案中那樣。
考慮到這一點,不向SC新增任何關於是否需要動態呼叫的後設資料並實現動態應用程式呼叫是有可能的,因為它們可以以相同的方式執行和延申。
但是,即使在可以實現一個系統可以動態SC呼叫和動態分片這種情況下,本提案仍認為儲存HasDynamicInvoke屬性在該實現中可能是很有用的。
儲存此屬性還能使系統對使用HasDynamicInvoke屬性發布的SC收取不同的費用。


向後相容性


本NEP介紹了一套不影響現有SC的新功能。
透過利用現有位元組來指示SC是否需要儲存區或新增額外標記,我們能夠在不影響現有網路協議的情況下維持現有功能和新增該新功能。


實現


• neo-project/neo: https://github.com/neo-project/neo/blob/master/neo/SmartContract/ApplicationEngine.cs
• neo-project/neo-vm: https://github.com/neo-project/neo-vm/blob/master/src/neo-vm/ExecutionEngine.cs

NEO改進協議提案5(NEP-5)

摘要

NEP-5提案概述了NEO區塊鏈的token標準,該標準將為系統提供token化的智慧合約的通用互動機制。其定義了這種機制以及其特徵的緣由。還提供了模板和示例以支援開發社羣。


動機


隨著NEO區塊鏈的發展,智慧合約的部署和呼叫變得越來越重要。如果沒有一個標準的互動方案,系統需要為每個合同維護一個唯一的API介面,無論其於其他合約的相似程度。token化合約自身就是這一需求的主要例子,由於其主要操作機制是相同的。與這些token互動的標準方法使得整個生態系統免於為每一個部署token的智慧合約維護所需基本操作的定義。


詳述


在下面方法定義中,我們提供合約中所定義的函式方法的定義以及其呼叫引數


方法


totalSupply
public static BigInteger totalSupply()
Returns 部署在系統內該token的總數.
name
public static string name()
Returns token的名稱. e.g. “MyToken”.
該方法每次被呼叫時必需返回一樣的值.
symbol
public static string symbol()
Returns 合約所管理的token的短字串符號 . e.g. “MYT”. 該符號需要應該比較短小 (建議3-8個字元), 沒有空白字元或換行符 ,並限制為大寫拉丁字母 (26個英文字元).
該方法每次被呼叫時必需返回一樣的值.
decimals
public static byte decimals()
Returns token使用的小數位數 – e.g. 8, 意味著把token數量除以100,000,000來獲得它的表示值.
該方法每次被呼叫時必需返回一樣的值.
balanceOf
public static BigInteger balanceOf(byte[] account)
Returns 賬戶的token金額.
引數賬戶必需是一個20位元組的地址。如果不是,該方法會丟擲一個異常。
如果該賬戶是個未被使用的地址,該方法會返回0
transfer
public static bool transfer(byte[] from, byte[] to, BigInteger amount)
從一個賬戶轉移一定數量的token到另一個賬戶.
引數from和to必需是20位元組的地址,否則,該方法會報錯。
引數amount必需大於等於0.否則,該方法會報錯。
如果賬戶沒有足夠的支付金額,該函式會返回false.
如果方法執行成功,會觸發轉移事件,並返回true,即使數量為0或者from和to是同一個地址
函式會檢查from的地址是否等於呼叫合約的hash.如果是,則轉移會被處理;否則,函式會呼叫SYSCALL Neo.Runtime.CheckWitness來確認轉移
如果to地址是一個部署合約,函式會檢查其payable標誌位來決定是否把token轉移到該合約。
如果轉移沒有被處理,函式會返回false.


事件


transfer


public static event transfer(byte[] from, byte[] to, BigInteger amount)
會在token被轉移時觸發,包括零值轉移。
一個建立新token的token合約在建立token時會觸發轉移事件,並將from的地址設定為null
一個銷燬token的token合約在銷燬token時會觸發轉移事件,並將to的地址設定為null


實現


• Woolong: https://github.com/lllwvlvwlll/Woolong
• ICO Template: https://github.com/neo-project/examples/tree/master/ICO_Template

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;