您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Oracle中區塊鏈的實現原理是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
在智能合約中執行的邏輯不可以執行區塊鏈之外的任何操作,例如它不可以訪問互聯網上的web服務。外部數據進入智能合約的唯一方法是將其置入一個交易中,通過向系統發送一個新的交易來觸發區塊鏈狀態的更新。
試著考慮一下,如果智能合約在執行時可以訪問外部的一個API來獲取數據,會出現什么情況?
如果今天部署這個合約,那么API可能會返回如下的數據:
{ "foo": "bar" }
但是明天再部署時,API可能就會返回新的數據,例如:
{ "foo": "baz" }
那么可以想像,一個月以后如果有人進行以太坊區塊鏈的同步,這個智能合約就會被執行,但是API的響應數據是和一個月之前不同的,這就會導致新同步的區塊鏈狀態不同于之前已經存在的節點狀態。
這就不再是完全自確定的區塊鏈了。經歷相同的同步過程,我的區塊鏈和你的區塊鏈卻不一樣!
讓我們再換個說法:給定一組區塊,一個節點必須能夠從零開始重現區塊鏈的最終狀態,而無需互聯網連接。
那么這一點對于智能合約的開發者意味著什么?Oralce(預言機),開發者必須構造一個預言機來和實現智能合約與外部世界的交互。
現在讓我們創建一個簡單的預言機/Oracle,來將外部的天氣數據傳入智能合約:
在最底層的區塊鏈平臺,我們需要部署一個智能合約,這個合約有一個方法updateWeather()
用來更新天氣狀態,只有在合約白名單里的地址才可以調用這個方法。updateWeather方法接受天氣數據作為參數,同時觸發一個以太坊合約事件并將天氣數據作為事件的參數,這樣JavaScript應用就可以訂閱這個事件并獲得異步通知了。
同時我們將創建兩個nodejs進程,其中之一就是預言機/Oracle,它的實現邏輯就是周期性地輪詢第三方天氣API來獲取天氣數據,然后將天氣數據提交給智能合約以便進行歷史審計。
另一個nodejs進程則負責訂閱智能合約的天氣事件,然后在控制臺輸出事件參數。正如之前所述,每當預言機/Oracle調用合約的updateWeather()方法時,都會觸發天氣事件。
需要指出的是,為了便于理解預言機的核心實現思路,下面的代碼進行了簡化,剔除了必要的錯誤處理,因此并不適用于生產環境。
源代碼在這里:
預言機合約 - https://github.com/decentorganization/weather-oracle-contract
預言機服務 - https://github.com/decentorganization/weather-oracle-service
接下來我們詳細講解這個簡單的預言機的實現。
智能合約有一個公開的oracleAddress狀態變量,用來表示允許調用智能合約的updateWeather 方法的賬戶地址,我們在構造函數中對其進行賦值:
contract WeatherOracle { address public oracleAddress; constructor (address _oracleAddress) public { oracleAddress = _oracleAddress; } // ... }
接下來我們要定義天氣事件,這個事件將在weatherUpdate()調用成功時觸發。同樣為了簡化,我們讓這個事件簡單的附帶一個表示溫度的字符串參數。
event WeatherUpdate (string temperature);
最后我們要實現updateWeather()方法。它的可見性為public,意思是可以從外部調用這個方法:
function updateWeather (string temperature) public { require(msg.sender == oracleAddress); emit WeatherUpdate (temperature); }
請注意require語句。只有當調用地址(msg.sender)和白名單地址(oracleAddress)一致時才允許繼續執行該方法,否則將回滾交易。
好了,就這么簡單。
我們的預言機就是一個簡單的nodejs服務。它使用request庫來調用外部天氣API,解析API的響應,然后構造并提交交易給智能合約,然后等一會兒,重復上面的工作,如此周而復始。
讓我們從訪問API開始,我們將API的地址放在一個環境變量里,以便在開發/生產環境切換時避免修改源代碼:
const options = { uri: process.env.WEATHER_URL, json: true }; const start = () => { request(options) .then(parseData) .then(updateWeather) .then(restart) .catch(error); };
下面的代碼用來解析API的響應結果:
const parseData = (body) => { return new Promise((resolve, reject) => { const temperature = body.main.temp.toString(); resolve({ temperature }); }); };
現在要做的就是構造一個調用智能合約的updateWeather()
方法的以太坊交易。注意account()
是一個異步方法,它的作用是載入一個以太坊賬戶,contract
是一個js對象,它包含了之前部署的WeatherOracle智能合約的部署地址和ABI接口數據。這些與智能合約相關的函數都來自于著名的web3開發包:)
const updateWeather = ({ temperature }) => { return new Promise((resolve, reject) => { account().then(account => { contract.updateWeather(temperature, { from: account }, (err, res) => { resolve(res); }); }); }); };
最后,我們只需要在指定超時后重新啟動這個過程即可。 wait()
函數將在指定的超時時間之后解析。
const restart = () => { wait(process.env.TIMEOUT).then(start); };
搞定了!上面的代碼實現了一個簡單服務,它可以從API獲取數據,然后再輸入智能合約。
注意:
當我們構造以太坊交易時,我們使用{from:account}
來指定調用賬戶,account
所指向的這個賬戶需要有一些以太幣來支付交易的手續費。
我們使用環境變量來配置一個私鑰,用來實例化account對象。這個私鑰必須是用來部署 WeatherOracle智能合約時傳入的那個白名單地址所對應的私鑰。
這是另一個簡單的nodejs服務。同樣,contract
是一個包含了合約的部署地址和ABI信息的js對象,調用WeatherUpdate
并傳入一個回調就是我們訂閱天氣事件的所有代碼:
const consume = () => { contract.WeatherUpdate((error, result) => { console.log("NEW WEATHER DATA EVENT ON SMART CONTRACT"); console.log("BLOCK NUMBER: "); console.log(" " + result.blockNumber) console.log("WEATHER DATA: "); console.log(result.args); console.log("\n"); }); }
當這個服務運行時,隨著交易成功入塊上鏈,它將會周期性地向控制臺輸出數據:
NEW WEATHER DATA EVENT ON SMART CONTRACT BLOCK NUMBER: 3424586 WEATHER DATA: { temperature: '74.75' }
以上就是Oracle中區塊鏈的實現原理是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。