嗯喻鳄,說好的智能合約呢扼倘?怎么開始轉(zhuǎn)賬了?
因?yàn)槌牵琔TXO轉(zhuǎn)賬是所有合約的基礎(chǔ)再菊,你一定聽說過交易手續(xù)費(fèi)這個概念,那么交易手續(xù)費(fèi)怎么支付呢颜曾?
這就是個問題了對吧纠拔。
UTXO這個事情本身就是和轉(zhuǎn)賬是一體化的,之前我們在基礎(chǔ)知識哪里講過UTXO泛豪,但是那里是講不清楚的稠诲,因?yàn)椴唤Y(jié)合轉(zhuǎn)賬來說UTXO那是不可能說的清楚的。
UTXO的名字 unspent transaction output候址,未花費(fèi)交易輸出
我們之前提到過找零的問題吕粹,賬戶A給B轉(zhuǎn)賬,需要輸入賬戶A的n個UTXO岗仑,然后一個輸出給B多少錢匹耕,剩余的錢一個輸出給A自己。
如果交易的輸出總額和輸入總額不匹配的時候荠雕,如果輸出總額>輸入總額稳其,交易會失敗。
如果輸出總額<輸入總額會怎樣炸卑?你的錢捐給系統(tǒng)了既鞠,就是這樣。
要支付交易手續(xù)費(fèi)盖文,就把他捐給系統(tǒng)吧嘱蛋。
然后我們來發(fā)一筆轉(zhuǎn)賬吧,首先講一講怎么發(fā)?我們要寫一個自己的輕錢包來發(fā)洒敏,怎么寫龄恋,用這個
https://github.com/NewEconoLab/neo-thinsdk-cs
這個項(xiàng)目提供了neo所需的那些加密運(yùn)算,你需要生成轉(zhuǎn)賬的交易凶伙、簽名郭毕、然后把他發(fā)布到鏈上。
1.生成轉(zhuǎn)賬交易
? ? 最終轉(zhuǎn)賬交易是個二進(jìn)制的數(shù)據(jù)塊函荣,怎么生成這個二進(jìn)制的塊显押,我們通常會寫一個數(shù)據(jù)結(jié)構(gòu),然后提供序列化方法傻挂,把數(shù)據(jù)結(jié)構(gòu)的內(nèi)容變成數(shù)據(jù)塊乘碑。
? ? 這個結(jié)構(gòu)叫做Transaction,thinsdk 當(dāng)然提供了transaction結(jié)構(gòu)和序列化方法踊谋,你也可以閱讀neo官方文檔蝉仇,其中有對二進(jìn)制數(shù)據(jù)構(gòu)成的描述。你也可以閱讀neo源代碼殖蚕,此處,只要會用就好沉迹。
class Transactoion
{
? ?type//交易類型
? ? vertion//交易版本 目前只有 0 1
? ? [type extdata]//每種交易類型獨(dú)有的數(shù)據(jù)睦疫,比如調(diào)用應(yīng)用合約交易,就得有調(diào)用腳本
? ??attributes//交易屬性(0到多個)鞭呕,可以附加一些東西蛤育,比如注釋啦,除輸入以外的附加鑒證人啦
????inputs//交易的輸入(0到多個)(utxo銷毀)
????outputs//交易的輸出(0到多個)(utxo產(chǎn)生)
? ? ?witnesses;//鑒證人(0到多個)
}
要填充一筆轉(zhuǎn)賬交易葫松,輸入是一個問題瓦糕,你要怎么知道一個賬戶到底有哪些utxo呢?thinsdk不管腋么,api管咕娄,看問后例子就好。
2.簽名交易
? ? 嗯珊擂,這里產(chǎn)生了一個概念圣勒,NEO把交易分為未簽名交易與已簽名交易。
不含鑒證人部分的交易稱為未簽名交易摧扇,那自然含有鑒證人部分的交易稱為簽名交易咯圣贸。
簽好名的交易序列化為二進(jìn)制塊,廣播扛稽,這個行為就叫做發(fā)交易
而簽名交易其實(shí)是一個非常不準(zhǔn)確的說法吁峻,只是簽名這個說法大部分人更容易理解
簽名過程是給交易填上鑒證人數(shù)據(jù),script attribute 和 inputs 會導(dǎo)致需要鑒證人,大部分人理解的就是:因?yàn)閕nputs來自我的賬戶用含,所以需要我的簽名矮慕。因?yàn)橐梦业腻X,所以需要我簽名耕餐。
簽名凡傅,就是將該交易的未簽名部分序列化為二進(jìn)制塊,然后調(diào)用ecc算法簽個名肠缔,把這個數(shù)據(jù)加點(diǎn)東西加入簽名的witnesses中夏跷。
實(shí)際上算簽名只是鑒證的一個特例。
交易簽名只是用了特例的名字命名了整個行為明未,交易簽名并不是一定在簽名槽华,只有需要的鑒證人要求簽名時才簽名。
這就講到智能合約的鑒證觸發(fā)器那里了趟妥,這個話題有空再講猫态,讓我們接著聊轉(zhuǎn)賬
3.發(fā)布交易
簽好名的交易序列化為二進(jìn)制塊,廣播披摄,這個行為就叫做發(fā)交易亲雪。
怎么廣播?thinsdk不管疚膊,api管义辕,看例子就好。
這里是例子
在smartcontractDemo中寓盗,有叫做轉(zhuǎn)賬的例子灌砖,這是一個netcore 命令行程序。
1.拼合約
例子中用了下面這個接口來獲取一個賬戶的所有utxo
Helper.HttpGet(api + "?method=getutxo&id=1?ms=['" + _addr + "']")
記得嗎傀蚌,rpc接口不能直接給你這個基显,你就沒法拼轉(zhuǎn)賬交易,所以要爬蟲要api善炫。
此處的api由NEL提供撩幽,不要問我api是多少,他可能會變销部,但是smartcontractDemo這個代碼里會保證api肯定是測試過的摸航。
看代碼
然后你可以看看我們是怎么拼裝一個轉(zhuǎn)賬交易的,有maketran方法舅桩,就是填充inputs outputs那些酱虎,不再贅述。
2.簽合約
byte[] msg = tran.GetMessage();//tran是交易擂涛,getmessage是得到未簽名交易的二進(jìn)制數(shù)據(jù)塊
byte[] signdata = ThinNeo.Helper.Sign(msg, prikey);//簽名算法读串,私鑰什么的都是寫死的聊记,sdk也支持從neo json格式打開私鑰,這個不介紹了恢暖。
tran.AddWitness(signdata, pubkey, address);//添加普通賬戶鑒證人排监,私鑰公鑰地址,全都是一個人
string txid = tran.GetHash().ToString();
byte[] data = tran.GetRawData();//得到簽名交易的二進(jìn)制數(shù)據(jù)塊
直接如代碼
3.發(fā)交易
string rawdata = ThinNeo.Helper.Bytes2HexString(data);
byte[] postdata;
var url = Helper.MakeRpcUrlPost(api, "sendrawtransaction", out postdata, new MyJson.JsonNode_ValueString(rawdata));
var result = await Helper.HttpPost(url, postdata);