NEO智能合約開發(一)不可能完成的任務

懸賞任務

茲有以下合約html

public static object Main(string method, object[] args)
{
if (Runtime.Trigger == TriggerType.Verification)
{
if (method == 「0214」)
return true;
}
return false;
}git

他的avm以下,他是一個鑑權合約,不須要發佈他。github

55c56b6c766b00527ac46c766b51527ac4616168164e656f2e52756e74696d652e47657454726967676572009c6c766b52527ac46c766b52c3642a00616c766b00c30430323134876c766b53527ac46c766b53c3640e00516c766b54527ac4620f0061006c766b54527ac46203006c766b54c3616c7566typescript

ScriptHash:0x86cf7371f5511257f682cc47be48563a3ff03f51json

Address:APBUyZNkemciUQurabSQBnnma7kGGhUPPLc#

在TestNet 上已經向此地址轉帳不少個gas了,誰拿走算誰的。app

該任務在多個大牛集中的地方放了24個小時,無人拿走。稱爲不可能的任務名至實歸。函數

急流勇退

這篇文字是一篇勸退文,勸你繞開鑑權合約的開發,先學習應用合約的開發。工具

官網(neo.org)文檔的學習曲線已經不是陡峭,而是斷崖式。學習

我採樣了一番,竟然沒有發現有人跟隨此文檔順利完成了鑑權合約的學習。

因而我懷着抱着滿滿的對本身學習能力的自信,去攀登這作陡峭的大山,打算學成歸來再教大家如何學習鑑權歸來。

我回來了,也是斷崖上跳下來的。

這兩筆是我從懸賞帳戶裏面取出來的錢。

那麼我成功了?部分紅功,在嘗試使用NEOGUI取這兩筆錢的路上,我徹底涼了。

我使用的是NEL Thinsdk-cs 的例子錢包取出來的(https://github.com/NewEconoLab/neo-thinsdk-cs)

完成這個任務以後,我才得出了以下結論:

建議你們繞開鑑權合約的開發,先學習應用合約的開發。

其難度主要在於須要理解的概念多,neogui配合不足。若是你看到這裏,仍是絕不氣餒,堅持要攀登這座大山,咱們一塊兒日後談。

密碼合約:

懸賞合約是一個密碼合約

public static object Main(string method, object[] args)
{
if (Runtime.Trigger == TriggerType.Verification)
{
if (method == 「0214」)
return true;
}
return false;
}

他只有在第一個參數爲0214,而且Runtime.Trigger==Verification時,返回true。

對鑑權合約來講,返回true這筆交易才能成立。

想起來很簡單,從哪裏傳入這個0214呢?這就得把整個交易和鑑權合約這一塊都說一說了。

鑑權合約與交易

鑑權合約是在交易驗證階段執行的,若是鑑權合約沒有返回true,那麼這筆交易直接驗證失敗,沒法被寫入區塊,也就不可能查詢到這筆交易。

鑑權合約和應用合約有着本質上的不一樣,應用合約必定是驗證成功寫入的區塊中執行。

NEO交易有輸入和輸出。這是UTXO模型的事情,交易的輸入是一個列表,其中每一項是對一個UTXO的引用。交易的輸出是製造新的UTXO。

交易的輸入輸出就是錢,銷燬輸入,製造輸出,對UTXO迷糊的同窗能夠不用看了,拐回去搞清楚UTXO。

交易包含以下內容:

  1. 輸入列表
  2. 輸出列表
  3. 若是是應用合約交易,還有應用合約腳本,其餘交易還有些別的

這些共同構成未簽名合約。

你是否是發現了,沒有鑑權合約什麼事情啊?鑑權合約呢?

你記得簽名麼?你必定知道給別人轉帳,要用你的私鑰,對交易進行簽名吧。

這其實,就是鑑權合約的一種特例。

1.取決於一個交易有幾個輸入地址(也就是出錢的人),就必須有幾個對應的見證人(witness)。

2.對交易進行簽名,就是添加對應轉帳發起人的見證人

3.NEO是一個完整的智能合約系統,每個見證人都是兩段腳本,一段叫校驗腳本,一段叫執行腳本。

以上三點是否是有些暈乎,別急,還有更暈乎的

簽名詳解

1.NEO的每個帳戶地址都是一段腳本,該腳本是一個兩條指令的智能合約,僞代碼爲:

Push publickey

Syscall Checkwitness

該腳本的hash值就是用戶地址,一般用戶地址用該hash值加鹽加驗證作base58以後的字符串形式表達。字符串形式和hash值徹底等價。

由此可知,NEO的地址,就是智能合約的hash值。反過來也成立,NEO每一個智能合約的hash值,都是一個地址。

因此,我能夠向一個智能合約轉帳,也能夠從一個智能合約取錢,由於個人地址,其實也是一個智能合約地址。

2.見證人的校驗腳本就是該地址對應的智能合約,且不可修改,hash不同通不過校驗。

3.見證人的執行腳本是用來像校驗腳本提供參數的智能合約。

因此咱們再來看從個人地址給別人轉帳發生了什麼。

1.給別人轉帳,必須輸入裏面由來自個人地址的utxo

2.構造交易

3.添加見證人,校驗腳本就是個人腳本

4.設置見證人執行腳本,他是一個一條指令的智能合約,僞代碼爲:

Push signdata

5.發送包含交易數據和見證人數據的rawdata

6.校驗交易,執行腳本 push signdata,結束,校驗腳本 push 本身的pubkey,而後checksig,該函數兩個參數,正好是signdata 和 pubkey,檢查,若是成功,交易成立。不然交易不成立。

簽名是否是比你想的要複雜不少呢。

拿走懸紅

搞清楚見證人和交易的關係以後,咱們纔可能順利的從懸賞合約中拿走錢

那就構造一筆轉帳交易

輸入n個,從懸賞合約地址裏找到utxo 作輸入

輸出1,給本身的地址

輸出2可選:能夠給懸賞地址找零

見證人:校驗腳本=懸賞合約

執行腳本=參數

由於參數爲一個 string 一個array

倒敘push

僞代碼爲

Push0 //加入0

Pack // 用上面的0 建立array,表示空array

Push bytes(「0214」.as bytes())//push 「0214」

二進制爲:00c10430323134

信息都告訴你了,那麼拼個自定義合約就好了唄。

NEOGUI不是有工具嗎,F12調出,是的,去測試吧,保證愉快。你就能理解斷崖式學習曲線是怎麼回事了。

並且就算你上面都作對了,你也拿不走。

我在此處納悶了好久,而後我一行行的跟進了NEO底層

這有一個限制,執行腳本里面只能容許push指令,不然直接腳本執行失敗了,鑑權合約失敗,交易不成立。

咱們剛纔的執行腳本僞代碼爲

Push0 //加入0

Pack // 用上面的0 建立array,表示空array

Push bytes(「0214」.as bytes())//push 「0214」

二進制爲:00c10430323134

有一個pack,超出容許範圍,交易必定失敗。

那麼咱們知道了,鑑權合約裏面是沒辦法引用array 類型的參數了。

好在懸賞合約的第二個參數其實沒有使用,隨便推個啥就行

咱們把執行腳本改成

Push0 //加入0

Push bytes(「0214」.as bytes())//push 「0214」

二進制爲:000430323134

好了,若是你頗有耐心,去玩NEOGUI 和 F12吧。

沒有發佈?

你若是看了一些NEO智能合約的資料,你也許會發現,這個合約沒發佈呀。

智能合約是不須要發佈的,智能合約是不須要發佈的,你能夠直接調用,沒問題。

那麼什麼狀況要發佈呢,這個智能合約要被appcall 調用的話,他必須被髮布到鏈上,支付昂貴的費用。應用合約基本上都是這種,爲了方便反覆調用,還有內部存儲。

加上全部這些,從應用合約入門,仍是比鑑權合約入門簡單不少。

鑑權合約不用發佈。

另外一個客戶端是怎麼回事

這是NEL(一個 NEO中國開發者社區 組織)

爲了開發輕錢包準備的 sdk的例子

C#版本

https://github.com/NewEconoLab/neo-thinsdk-cs

typescript版本

https://github.com/NewEconoLab/neo-thinsdk-ts

咱們來演示一下,用這個例子錢包,如何更順暢的學習鑑權合約

NEL公衆號有發佈過這個錢包轉帳的方法

http://www.cnblogs.com/crazylights/p/8338117.htm

啓動c#例子

點下面的 thinWallet test,就是一個輕錢包測試了

由於咱們取懸紅,其實並不須要loadkey,就是打開錢包,咱們不須要任何人簽名就能把錢給取了

從懸賞合約地址取得utxo

在Input區域點右鍵,能夠用智能合約增長一個UTXO

將懸紅合約copy進來,或者點擊loadavm 從avm讀取

則能夠看到合約的地址顯示在下邊

而後點refresh utxo,能夠獲得宣紅合約的utxo,選一個

咱們選91.8這個

而後看到輸入有了

輸出多了一個(changeback)表示是找零,咱們是好青年,不全拿走

見證人(witness)也自動添加了一個(sc)是智能合約簡稱

加個輸出,轉給本身

在輸出區域 右鍵,添加一個輸出

填好轉給誰,幣種(gas),多少

而後輸出自動調整找零

試試簽名發出,發不出去,告訴你見證人的執行腳本還沒配置

配置見證人

選中見證人,在見證人區域 右鍵

黃色是校驗腳本,他就是懸賞合約自己,不能夠修改

紅色是執行腳本的配置,咱們用一個json替代不直觀的配置

String 加了點規則

(str)開頭表示這是個字符串

(int)開頭表示這是個biginteger

還有(bin)(int160)(int256)

很好懂吧。

點擊Gencode 就生成了執行腳本,可是咱們已知,帶Array的執行腳本不容許,改一下。

好,點ok

回來點簽名並廣播

Done,成功,

獲得一個交易id對話框

交易成功

隨便去哪裏查,均可以看到懸紅裏的錢已經取出了。

寫在最後

懸紅裏還留了不少錢,留給那些想要探索的人,請不要一次取完。

做者:李劍英

原文轉自:http://www.javashuo.com/article/p-wjjacsts-r.html

相關文章
相關標籤/搜索