# ChainLink 原理
- Oracle 为智能合约提供外部数据源的系统
- 区块链是一个交易驱动的状态机
- 任何好的信息来源都可以称为oracle
- 不管是“预言机”还是“甲骨文”都表达了“信息源”的意思
- ChainLink 是一個去中心化的预言机项目
各式各樣的 Oracle 架構要解決的都是同一個問題:
### 「如何『安全地』把鏈外的『正確』資訊送入鏈上的智慧合約中」
### 盡可能減少 Oracle 餵入錯誤資訊的動機,或是增加這麼做的成本
### 隨著市場規模的擴大,Oracle 的攻擊成本也要相應的提升
```
预言机的基本原理。我们在以太坊链上建立一个用户合约,它需要获取到某个城市的气温数据。当然,智能合约自己是无法获取到这个发生于链下真实世界中的数据信息的,需要借助预言机来实现。智能合约将需要获取天气温度的的城市写入到EventLog中,链下我们会启动一个进程,监听并订阅这个事件日志,获取到智能合约的请求之后,将指定城市的温度,通过提交transaction的方式,调用合约中的回填方法,提交到智能合约中。
```
![](https://hackmd.io/_uploads/B1Bv14a3Y.png)
```solidity=
contract WeatherOracle {
// 用户存储预言机提交的天气数值
uint256 public temperature;
// 定义事件
event RequestTemperature (bytes city);
// 发出获取请求,即发出一个事件日志
function requestTemperature (string memory _city) public {
emit RequestTemperature(bytes(_city));
}
// 预言机回调方法,预言机获取到数据后通过这个方法将数据提交到链上
function updateWeather (uint256 _temperature) public {
temperature = _temperature;
}
}
```
```solidity=
func SubscribeEventLog() {
topic := crypto.Keccak256([]byte("RequestTemperature(bytes)"))
query := ethereum.FilterQuery{
Topics: [][]common.Hash{
{
common.BytesToHash(topic),
},
},
}
// 订阅相关主题的日志事件
events := make(chan types.Log)
sub, err := EthClient.SubscribeFilterLogs(ctx, query, events)
// 加载合约的ABI文件
ta, err := abi.JSON(strings.NewReader(AbiJsonStr))
// 监听事件订阅
for {
select {
case err := <-sub.Err():
log.Error(err)
break
case ev := <-events:
// 获取到订阅的消息
ej, _ := ev.MarshalJSON()
log.Info(string(ej))
// 解析数据
var sampleEvent struct {
City []byte
}
err = ta.Unpack(&sampleEvent, "RequestTemperature", ev.Data)
log.Info(string(sampleEvent.City))
// 构建交易提交结果,需要提供私钥用于签署交易
CallContract("b7b502b...164b42c")
}
}
}
```
```solidity=
func CallContract(keyStr string) {
addr := PrivateKeyToAddress(keyStr)
nonce, err := EthClient.PendingNonceAt(ctx, addr)
gasPrice, err := EthClient.SuggestGasPrice(ctx)
privateKey, err := crypto.HexToECDSA(keyStr)
auth := bind.NewKeyedTransactor(privateKey)
auth.Nonce = big.NewInt(int64(nonce))
auth.Value = big.NewInt(0)
auth.GasLimit = uint64(300000)
auth.GasPrice = gasPrice
instance, err := event.NewEvent(common.HexToAddress("0x8A421906e9562AA1c71e5a32De1cf75161C5A463"), EthClient)
// 调用合约中的updateWeather方法,回填数据"29"
tx, err := instance.UpdateWeather(auth, big.NewInt(29))
log.Info(tx.Hash().Hex())
}
```
![](https://hackmd.io/_uploads/BkAzgNp3t.png)
一句話解釋:透過訂閱Event將外部數據帶回到鏈上
![](https://hackmd.io/_uploads/rkE9-46nt.png)
![](https://hackmd.io/_uploads/HyCTXNant.png)
心得:只要有好的共識機制,藉由多個feed,可以確保數據的真實性
```
Chainlink 的架構核心即為由許多的數據提供者組成的鏈外「Chainlink 節點網路」,想要成為在 Chainlink 網路中提供數據的節點必須要抵押特定量的 Chainlink 平台治理代幣「LINK」Token。使用者如果想要透過 Chainlink 來取得數據資訊時需要以 LINK 來支付費用,而這些 LINK 將會分配給提供正確數據資訊的節點們作為報酬。而提供錯誤資訊或是有其它異常行為的節點將會被扣除部分抵押的 LINK 作為懲罰。
```
Chainlink最近在门限签名领域实现了突破,门限签名技术让智能合约可以同时使用多个预言机,但只需支付链上费用。这项技术史无前例地大幅降低了去中心化预言机的使用成本。
Chainlink另一个特色就是其信誉系统。与阿里巴巴和滴滴平台中卖家和司机的信誉系统类似,Chainlink也为预言机开发了一套信誉系统。声誉由各种衡量指标构成,其中包括运行时间、响应时间以及成功完成的任务。智能合约的数据请求方可以根据预言机评分来选择,或者也可随机选择。这个信誉系统不仅为开发者提供了可靠的参考指标,还约束了各个节点为其提供的服务负责。
## 心得
狀態機:相同輸入 -> 相同輸出
預言機:喂真實世界的數據
不再有中心化機構來維護,不用取得共識
每個人只要成為節點,都可以自主運用這些數據來整合
成為節點的人可以獲取獎勵,節點眾籌
比如光是一個睡眠的數據,有人可以直接拿來記錄用,有人可能結合自身基因跟身體指數,結合變成睡眠對於健康數據
## 補充 ChainLink 應用
[DEFI/去中心化金融](http://blog.hubwiz.com/2020/12/01/chainlink-usecase-77/)
![](https://hackmd.io/_uploads/HJFNQra2F.png)
![](https://hackmd.io/_uploads/rJ0T7BTnt.png)
![](https://hackmd.io/_uploads/ByfpQSahY.png)
## Reference
- https://upyun-assets.ethfans.org/posts/chainlink-oracle-basics
- https://upyun-assets.ethfans.org/posts/chainlink-oracle-basics
- https://blog.csdn.net/ChainlinkO/article/details/112799366
- https://zhuanlan.zhihu.com/p/107468462