Вы можете использовать Chainlink в качестве Oracle.
Как многие уже упоминали, вам понадобится oracle, чтобы получить вызов API. Важно отметить, что ваш контракт на самом деле просит oracle сделать ваш вызов API за вас, а не сам вызов API. Это потому, что блокчейн детерминирован c. Для получения дополнительной информации см. этот поток .
Чтобы ответить на ваш вопрос, вы можете использовать децентрализованный oracle сервис Chainlink .
You'd добавить функцию:
function getWinner()
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(JOB, address(this), this.fulfill.selector);
req.add("get", "example-winner.com/winner");
req.add("path", "winner");
sendChainlinkRequestTo(ORACLE, req, ORACLE_PAYMENT);
}
В целях следующего примера мы будем делать вид, что вы хотите вернуть uint256
вместо адреса. Вы можете вернуть bytes32, а затем преобразовать его в адрес, но для простоты предположим, что API возвращает индекс победителя. Вам нужно будет найти узел и jobId, которые могут сделать запрос http.get
и вернуть объект uint256
. Вы можете найти узлы и вакансии по ссылке market.link . Каждый tes tnet (Ropsten, Mai nnet, Kovan, et c) имеет разные адреса узлов, поэтому убедитесь, что вы выбрали правильные.
Для этой демонстрации мы будем использовать LinkPool. узел ropsten
address ORACLE=0x83F00b902cbf06E316C95F51cbEeD9D2572a349a;
bytes32 JOB= "c179a8180e034cf5a341488406c32827";
В идеале вы должны выбрать количество узлов для выполнения вашей работы, чтобы сделать ее недоверчивой и децентрализованной. Вы можете прочитать здесь для получения дополнительной информации о предварительных координаторах и агрегировании данных. раскрытие информации Я являюсь автором этого блога
Ваш полный контракт будет выглядеть так:
pragma solidity ^0.6.0;
import "github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/ChainlinkClient.sol";
contract GetData is ChainlinkClient {
uint256 indexOfWinner;
address public manager;
address payable[] public players;
uint256 MINIMUM = 1000000000000000;
// The address of an oracle
address ORACLE=0x83F00b902cbf06E316C95F51cbEeD9D2572a349a;
//bytes32 JOB= "93fedd3377a54d8dac6b4ceadd78ac34";
bytes32 JOB= "c179a8180e034cf5a341488406c32827";
uint256 ORACLE_PAYMENT = 1 * LINK;
constructor() public {
setPublicChainlinkToken();
manager = msg.sender;
}
function getWinnerAddress()
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(JOB, address(this), this.fulfill.selector);
req.add("get", "example-winner.com/winner");
req.add("path", "winner");
sendChainlinkRequestTo(ORACLE, req, ORACLE_PAYMENT);
}
// When the URL finishes, the response is routed to this function
function fulfill(bytes32 _requestId, uint256 _index)
public
recordChainlinkFulfillment(_requestId)
{
indexOfWinner = _index;
assert(msg.sender == manager);
players[indexOfWinner].transfer(address(this).balance);
players = new address payable[](0);
}
function enter() public payable{
assert(msg.value > MINIMUM);
players.push(msg.sender);
}
modifier onlyOwner() {
require(msg.sender == manager);
_;
}
// Allows the owner to withdraw their LINK on this contract
function withdrawLink() external onlyOwner() {
LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress());
require(_link.transfer(msg.sender, _link.balanceOf(address(this))), "Unable to transfer");
}
}
Это сделает все, что вам нужно.
Если вы не можете настроить API для возврата uint, вы можете вернуть bytes32, а затем преобразовать его в адрес или строку.
function bytes32ToStr(bytes32 _bytes32) public pure returns (string memory) {
bytes memory bytesArray = new bytes(32);
for (uint256 i; i < 32; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}