NEO智慧合約開發(二)再續不可能的任務

NEOGO發表於2019-01-23

NEO智慧合約開發中,應用合約比較簡單,是的你沒看錯,應用合約比較簡單。

應用合約三部曲,釋出、呼叫、看結果。除了看結果工具比較缺乏,釋出呼叫neogui最起碼可以支撐你測試。

鑑權合約比較麻煩,因為neogui不能支援你很好的測試鑑權合約。

這是一個難點,上一次我們讓你試著用鑑權合約往外取錢了,一個密碼,有了密碼誰都能取錢。就那,用neogui去取並不容易,對吧。

這一次我們繼續探討這個話題,一個更有價值的應用場景。

如何限制一個使用者能從智慧合約裡取出多少錢?

不用擔心,如果到這裡你啥都看不懂,很正常。我估計中國真的理解了NEO的鑑權機制的人一雙手就數的過來。一個正常的NEO學習機制,應該是:

  1. 先開發一個錢包客戶端
  2. 然後瞭解應用合約的呼叫,用自己的錢包客戶端,自己寫的的scriptbuilder,去完成應用合約的呼叫。
  3. 瞭解鑑權合約,寫一些鑑權合約,用自己的錢包客戶端拼交易,測試他們。

NEO官網上提供的資訊太少,不看NEO原始碼,沒有正常人類能通過NEO官網的資料學會這些內容。

如果你還沒有到這個階段,這篇文字還不適合你,去做一些應該做的事情吧。

限制取錢機制有什麼意義

比如說,Nep5的ico機制,使用者投入NEO,得到Nep5代幣。這就是一個自動販賣機機制。你給我gas或者neo,我給你遊戲幣。用UTXO資產,購買NEP5資產,或者其它什麼東西。

那麼NEO現在提供的ico模板,是沒有退貨機制的。因為比較難實現,不好限制使用者從ico合約裡面能取出多少錢。

這就是意義,能做到限制取多少錢,就能實現ICO自動化退貨機制。

換個比方,售貨機機制還有很多作用,比如我幫我的朋友存一筆錢,他生日到了可以取走。

比如兩個人打du,猜一下五個區塊以後的一個隨機數的單雙,聰明的你馬上懂了,實現了使用者能從智慧合約裡面取出多少UTXO資產的限制,就可以直接用UTXO資產進行各種不可描述的du博業務。

再往遠了想一想,一個全自動化的交易所,用GAS買入某種NEO代幣,等他漲了再賣掉,把GAS取出來。我還沒有看過藍鯨濤公佈原始碼,neox的原始碼我也沒有研究。那這就是他們實現使用者自己提取UTXO資產的一個核心機制。

這有什麼困難的?

很難,第一反應就是storage直接存個值,取得時候存一下,根據這個值,就可以實現任意限制邏輯。

想的美。

100個GAS在這放著,有本事去取呀。

放心你取不出來。

這個合約表面上看誰都能取,但是Storage.Put 引發異常,實際上誰也取不出來。

你看,你想的最美的通過Storage去限制取多少,做不到。在鑑權合約觸發時,Storage.Put 整個不能用。

回想一下ICO模板,是不是沒有實現全自動的退款,準確點說就是沒有實現任意使用者從智慧合約提取NEO。就是這個原因。

那就沒有辦法了嘛?

有一個金句,辦法總比困難多。

如果你只是簡單的縱覽一下,可能會覺得儲存這條路被堵住了,一切都不可行了。

讓我們仔細來看一下這個邏輯

  1. 需要有個限制取錢的機制,取完就不能再取
  2. 需要用Stroage來控制這個機制
  3. 鑑權合約執行時不能Storage.Put

看起來好像邏輯鏈斷了,但是當我們想起來UTXO資產本身的一個特質,這個鏈條就會再次接上。一個UTXO只能被使用一次,沒錯就是他。這個不正好可以用來控制使用者能取多少錢了麼?

一、需要有個限制取錢的機制(給每個取錢的使用者一個專屬的UTXO只能他取)

二、需要用Stroage來控制這個機制(storage直接存一個map<utxo,targetaddr>,限制一個utxo只能向一個固定地址轉賬)

三、鑑權合約執行時不能Storage.put(但是可以Storage.get 呀,bingo)

我們把思路稍微調整了一下,就接上了。我們不需要storage直接控制一個使用者能取多少錢。1.用storage 控制一個utxo能往哪個地址轉賬,這可以實現。

2.一個utxo只能轉賬一次,這是天然的。

這兩條加一起,這個自助提取UTXO資產的邏輯就通了。

用兩筆交易實現自助提取UTXO資產。

第一筆,資產不離開智慧合約,智慧合約向自身轉賬,生成某使用者專用的UTXO,同時做invoke應用合約,記錄將此UTXO專用化。

第二筆,取錢,用此專用UTXO向使用者地址轉賬。

實踐一下

直接看程式碼

這裡只是為了探究這個機制,我們將第一步設定為由超級管理員給使用者撒錢。你仔細想想,實現個使用者自己從自己的NEP5地址退錢,和這並沒太大區別。我們不要讓那麼多程式碼來干擾我們實現核心機制。

第一步

用這個智慧合約自己給自己轉賬

如圖,就是Gas1000,轉給自己100GAS,找零900Gas這筆,錢沒有離開智慧合約地址。

然後超級管理員給超級管理員轉賬 30536.6 GAS這筆,超級管理員也沒出錢。

然後同時呼叫智慧合約,將該筆交易第0個輸出的UTXO,設定為只能向地址

AcfW….轉賬,如圖

由於使用了智慧合約,需要一個SC的witness,如下圖,隨便傳倆引數,不能用Array

讓我們分析下上面做了什麼

1.智慧合約給自己轉賬,第零個輸出是個utxo,100gas,那就意味著,我們允許AcfW…這個地址從智慧合約地址裡面轉走100GAS

2.超級管理員給自己轉賬,這個不產生直接價值

他只是為了讓鑑權合約能走到這裡,附加上超級管理員的鑑證,就隨便怎麼轉都行。

也可以使用交易的Attribute附加上超級管理員的鑑證指令碼。

  1. APPcall givemoney(0,Acfw…)

就是這部分程式碼了,將本交易的hash和本交易的第0個輸出編成一個Key。

你也許注意到我寫了一個ConvertN函式,因為整數的byte[] 形態是什麼不太穩定,我需要他是確定的,要不然0000 00 和空byte[] 都表示0,那key就亂套了

然後你看到我直接stroage.put 將目標地址存了起來。這就是第一步。

製造一個100GAS的UTXO,並且在Storage裡記錄下來給誰。

第二步

第二步就簡單了,這交易不需要任何人簽名

,智慧合約的鑑證指令碼也是隨便填就行

然後你就可以取到錢啦。

分析一下

我把這段鑑權合約分為了三個部分

紅色部分是判斷,這筆交易,只允許有一個輸入一個輸出,否則你取不走錢。當然你用迴圈可以處理更復雜的情況,記住我們只是在探究這個機制。

黃色部分是從儲存裡取到這個UTXO允許的目標

藍色部分是判斷這筆交易的輸出目標和Storage裡存的是否一致。

一致,錢你拿走,UTXO銷燬。

不一致,交易不成立,UTXO還在那裡。

我們做了什麼

綜上所述,我們提出了一種可以在NEO框架上實現使用者在智慧合約限制下提取UTXO資產的機制,並寫程式碼進行了驗證。

此機制可用於:

  1. 使用NEO的UTXO資產如NEO、GAS 進行ICO的退貨機制。
  2. 擴充套件上一條,可自動販賣某種數字資產以及退貨。
  3. 使用NEO的UTXO資產進行的彩票、下注等活動。
  4. 去中心化交易所的實現。


技術群交流:795681763

原文:https://www.cnblogs.com/crazylights/p/8457392.html


相關文章