1.5M ratings
277k ratings

回憶的沙漏

拼圖一片片失落
像楓葉的冷漠
牆上的鐘
默默數著寂寞

咖啡飄散過香味
剩苦澀陪著我
想念的心
埋葬我在深夜的脆弱

無盡的蒼穹 
滿天的星座
你的光亮 一閃而過
只想要記住這永恆的瞬間

像流星的墜落 
燦爛奪去了輪廓
這剎那過後 
世界只是 回憶的沙漏

像流星的墜落 
絢麗地點亮了整個星空
像你故事在 我生命留下 
不褪色的傷口

湖水守候著沈默
等待天邊的月
孤獨的水面 
卻漆黑整夜

夜霧凝結的淚光
被蒸發在角落
他無情地 
遺忘我在追憶的漩渦

無盡的蒼穹 
滿天的星座
你的光亮 一閃而過
只想要記住這永恆的瞬間

像流星的墜落 
燦爛奪去了輪廓
這剎那過後 
世界只是 
回憶的沙漏

像流星的墜落 
絢麗地點亮了整個星空
像你故事在 我生命留下 
不褪色的傷口

在黑夜的盡頭
是你的捉弄
和無聲的傷痛
燃燒過後
只剩靜默

像流星的墜落 
燦爛奪去了輪廓
這剎那過後 
世界只是 
回憶的沙漏

流星墜落 
絢麗地點亮了整個星空
像你故事在我生命留下 
不褪色的傷口

智慧合約的操作

接續上一篇。

儘管文件流程底層、金流、Line 與 FB 機器人、支援價值流體系的代幣系統建置完成;在生態建立完整之前,關閉代幣系統的交易機制仍舊是比較安全的作法。剛好以此為例,來說明對於一個已經部署完成的智慧合約,如何進行操作。

取用既有合約,有兩個方法:

一、延續上篇,當合約部署完成,名稱為 contract;下一個區塊挖出之前,只得到其交易序號 transactionHash。等到區塊挖出之後,可以透過下列在控制台內的指令,直接取用合約:

loadScript(‘abi’); // 如果還沒載入
var tx = contract.transactionHash;
var address = eth.getTransactionReceipt(tx).contractAddress;
var contract = abi.at(address);

二、一個已經部署的合約,可以在 etherscan.io 上找到這個合約的位址。舉 LTW 代幣為例,在首頁右上方的空格中,鍵入 LTW,就可以找得到。

合約位址為 0x63f40b2e061d231cd49c32f6b5afef17993c2c1d。

接著在控制台內執行下列指令:

loadScript('abi’); // 如果還沒載入
var address = ‘0x63f40b2e061d231cd49c32f6b5afef17993c2c1d’;
var contract = abi.at(address);

就能取用合約 contract。接著參照其 abi 檔案,獲得該合約的取用介面。

由於 LTW 使用代理合約的方式,合約位址不是合約主體所在;加上生態尚未完成,代幣還沒有真正運作,所以合約原始碼不在 etherscan.io。

不過在交易機制中,存在 buyPrice 和 sellPrice 這兩個變數,以及 setPrices() 這個方法;現在我們可以來看看如何取用這三個介面。

首先可以查看買價與賣價的值:

contract.buyPrice(); // 透過方法取用變數
contract.sellPrice(); // 透過方法取用變數

因為關閉了交易機制,所以這兩個值現在都顯示為 0。

而在稍早,我們花費了 gas 進行了如下設定:

contract.setPrices(0,0,{gasPrice:gas_price,from:eth.accounts[0]});

其中,

  • setPrices: 合約內設定買價與賣價的介面方法。
  • 0,0: 分別為所要設定的買價和賣價的值。
  • gasPrice: 給定的 gas 價格;gas 是操作合約的成本。稍後我們討論如何取得最低的 gas 價格。
  • from: 操作的帳戶。

這樣就透過合約的介面完成設定操作。

當然這個介面只有獲得授權者才能取用。在公開的環境之下,智慧合約的安全設計至關重要,不過這是另外一個將來討論的議題。


接下來是如何取得最便宜的 gas 價格進行合約的操作。首先參照這個網站頁面:

https://ethgasstation.info/txPoolReport.php

第一行 gas 價格,單位是 Gwei;最後一行和倒數第四行,分別列出目前在鏈上,對應的 gas 價格,在 30 分鐘與 5 分鐘之內,還積存著未被挖出的交易。

從這個即時資訊,就可以獲知最適 gas 價格,進行上述 gasPrice 的設定。

實際交易計算量所耗費的 gas 數量,乘上 gas 價格之後,就是所花費的成本。

如果在發出交易之後,gas 的價格提升,導致交易沒有辦法很快地完成,可以透過對 nonce 的設定,重新再發一條交易加以覆蓋。因為是更進階的操作,需要的人可以透過 nonce 這個關鍵字搜尋,或者交流討論。

智慧合約開發紀實

做個收尾,也更新一下記憶,把智慧合約的開發過程整理一下,也權當與習慣在 CLI 上開發者的一個交流。非常快速的一個記錄或許不盡詳細。

用到的工具只有 geth 與 solc。安裝過程很簡易也很容易找到,就不多作敘述。

關鍵在兩個部分與觀念:一個是建立本地開發環境的私有鏈;一個是與主鏈同步的 light 節點。

能夠在本地的私有鏈運行,就可以順利上到主鏈。所以先簡單講述一下 light 節點,後面在私有鏈上的操作過程與主鏈上的完全無異。

首先打開一個自己的輕量節點:

geth –datadir “/path/to/pub/eth” –syncmode “light”

一開始需要等待一些時間,因為輕量節點仰賴特殊全節點的支援,需要一點搜尋的時間。第一次連接上之後,有一個秘訣可以縮短下次的時間。

打開一個新的視窗,接入前面已經打開的輕量節點:

geth –datadir “/path/to/pub/eth” –syncmode “light” attach ipc:/path/to/pub/eth/geth.ipc

在控制台內鍵入:

admin.peers

會顯示出已經連接上的全節點,在 enode 的這個欄位,可以看到一列格式如: “enode://[node]@[address]:[port]”

每一次都把這一串記下來,會累積好幾個全節點的資料;下回連線的時候,就可以在控制台內輸入下面的指令,很快就可以連接上主鏈:

admin.addPeer(“enode://[node]@[address]:[port]”)

同步的時間很快,不到一個小時一個輕量節點就可以同步完成,進行後續的開發部署。唯一的差別就是,這個節點不能挖礦;不過對於開發者來說不是問題就是。

─ 明天要選舉了,先融入大家現在的氛圍,同一篇後續接著完成 @20181123 ─

現在回到本地建立開發環境的私有鏈。建立的方式雷同:

geth –datadir “/path/to/pri/eth” –dev –port 30303 –rpcport 8545 –nodiscover

要注意路徑,與建立主鏈的輕量節點是不一樣的,否則先前已經同步的主鏈資料會被覆蓋。幾個參數說明:

–dev: 在建立的時候就會分配金額在你的帳戶,以利後續測試使用。
–port: 默認是30303。如果有不同的私鏈或模擬節點同時存在才需要設定。
–rpcport: 默認8545。如果有不同的私鏈或模擬節點同時存在才需要設定。
–nodiscover: 防止不小心在公開環境下加入到其他的鏈。

上頭的參數設定,如果只是單純的開發環境,只需要設定到 –dev 就行,後面的可以省略。

接下來是重頭戲。智慧合約的編寫暫時略過;編譯一份使用 Solidity 語言寫好,名稱為 contract.sol 的合約:

solc –overwrite -o . –abi –bin –gas contract.sol

其中的參數:

–overwrite: 直接覆寫之前已經存在的 abi 跟 bin 檔案。
-o: 指定輸出檔案的路徑。
–abi: 產出 abi (Application Binary Interface) 檔案。這個檔案描述所編寫合約的介面,未來讓取用者知道如何取用這個合約。
–bin: 產出 bin 檔案。這是編譯完成的合約主體,讓鏈上的虛擬機知道怎麼執行。
–gas: 會在輸出顯示預估所需要的 gas 數量供參考用。

如果一份檔案裡有幾個不同的合約,會分別產生相對應的 abi 跟 bin 檔案。這邊我們假設只有一份合約,產生一個 abi 和 bin 檔。

控制台是 javascript 的環境。為了方便稍後的操作,我們在 CLI 作幾個初步的處理:

echo “abi = eth.contract($(<contract.abi));” > abi

echo “bin = ‘0x$(<contract.bin)’;” > bin

除了修改的 abi 跟 bin 這兩個檔案,我們產生第三個檔案內容如下,

est = eth.estimateGas({data:bin});
gas_price = eth.gasPrice;
console.log(“# estGas: ”+est);
console.log(“# estWei: ”+est*gas_price);
console.log(“# estEth: ”+web3.fromWei(est*gas_price,“ether”));
contract = abi.new({from:eth.accounts[0],data:bin,gas:est,gasPrice:gas_price});

其中的意義,在稍後於控制台內執行這些指令:

  • est: 預估所使用的 gas。
  • gas_price: 取得目前鏈上 gas 的市價。更便宜的價格需要複雜一點的操作,未來再來分享 請參閱這一篇。
  • console.log 等三列分別顯示想知道的資訊。
  • 最後一列會將合約依據指定的帳號、已經完成編譯的合約、給定的 gas 與價格,部署到區塊鏈上。

最後將這三個檔案合併起來,假設命名為 abc;現在從檔案所在的路徑進入控制台:

geth –datadir “/path/to/pri/eth” –dev –port 30303 –rpcport 8545 –nodiscover attach ipc:/path/to/pri/eth/geth.ipc

一樣需要注意 ipc 指定的路徑與主鏈的不同。

在控制台內執行指令:

loadScript('abc’)

智慧合約部署完成!名稱為 contract。

─ 先作為 part 1,之後繼續補充 @20181124 ─

下一篇。

當年左手邊是個人電腦,悠遊各大學的BBS跟Gopher。

右手邊就是昇陽的工作站,在Unix處理實驗用的影像資料─嚴格來說是Unix-like。

Mosaic剛出現;網景還沒看到。

昇陽的工作站對當時的我們來說是高大上的存在。

-

工作之後都在硬體產業,微軟的各式工具跟環境就很少接觸。再碰到就是Linux;從Unix到Linux無縫接軌也是一種幸福。

回想起來,90年代以前這些脈動感覺離著好近;2000年之後左邊有 BAT 右邊有 FAANG,卻有一種愈來愈遠的感覺。