NEO智能合约开发(一)不可能完成的任务
懸賞任務
茲有如下合約
public static object Main(string method, object[] args)
{
if (Runtime.Trigger == TriggerType.Verification)
{
if (method == "0214")
return true;
}
return false;
}
他的avm如下,他是一個鑒權合約,不需要發布他。
55c56b6c766b00527ac46c766b51527ac4616168164e656f2e52756e74696d652e47657454726967676572009c6c766b52527ac46c766b52c3642a00616c766b00c30430323134876c766b53527ac46c766b53c3640e00516c766b54527ac4620f0061006c766b54527ac46203006c766b54c3616c7566
ScriptHash:0x86cf7371f5511257f682cc47be48563a3ff03f51
Address:APBUyZNkemciUQurabSQBnnma7kGGhUPPL
在TestNet 上已經向此地址轉賬很多個gas了,誰拿走算誰的。
?
該任務在多個大牛集中的地方放了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.取決于一個交易有幾個輸入地址(也就是出錢的人),就必須有幾個對應的見證人(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對話框
?
交易成功
隨便去哪里查,都可以看到懸紅里的錢已經取出了。
?
寫在最后
懸紅里還留了很多錢,留給那些想要探索的人,請不要一次取完。
總結
以上是生活随笔為你收集整理的NEO智能合约开发(一)不可能完成的任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 音视频深入 十一
- 下一篇: 【1】万魂杀MMORPG研发回顾