基础不牢固地洞山摇

    科技2022-07-12  147

    基础不牢固地洞山摇

    Making HTTP requests in Solidity is simple with Chainlink. If you’d like more insight on best practices, then after reading this article be sure to read API calls on Blockchain.

    使用Chainlink, 在 Solidity中发出HTTP请求非常简单。 如果您想对最佳做法有更多的了解,那么在阅读本文之后,请务必阅读Blockchain上的API调用 。

    Let’s take a step back to start.

    让我们退后一步开始。

    发出链接请求如何工作? (How Does Making a Chainlink Request Work?)

    Remember that Chainlink oracles are blockchain middleware, so we need something to programmatically tell them to make an HTTP request. We need something to initiate them to start getting data for us. These instructions for telling a chainlink node to start getting data are called Chainlink Initiators.

    请记住, Chainlink oracle是区块链中间件,因此我们需要一些东西以编程方式告诉他们发出HTTP请求。 我们需要一些东西来启动他们开始获取数据我们。 这些告诉Chainlink节点开始获取数据的指令称为Chainlink Initiators 。

    A Chainlink node can have as many initiators as it likes. Each will define a different way for the node to start getting data.

    Chainlink节点可以具有任意数量的启动器。 每个节点都会为节点定义获取数据的不同方式。

    Initiator 1: Start getting data when x occurs

    发起方1:发生x时开始获取数据

    Initiator 2: Start getting data when y occurs

    发起方2:发生y时开始获取数据

    Initiator 3: Start getting data when z occurs

    发起方3:发生z时开始获取数据

    Etc…

    等等…

    Along with the initiators, as well as a set of instructions for what to do when they are initiated. This set of instructions about what to do are called the “tasks” or “adapters” list.

    连同启动程序,以及启动程序时的操作说明集。 这套关于操作的指令集称为“任务”或“ 适配器 ”列表。

    Adapter 1: Do q to data once received

    适配器1:对q接收到的数据执行q

    Adapter 2: Do r to data once received

    适配器2:收到数据后立即处理

    Adapter 3: Do s to data once received

    适配器3:收到数据后立即处理

    Etc…

    等等…

    The combination of initiators and adapters makes up a single job on a chainlink node. Chainlink nodes can have multiple jobs defined so that they can do many different things in a simple interface.

    启动程序和适配器的组合构成了链链接节点上的单个作业 。 Chainlink节点可以定义多个作业,以便它们可以在一个简单的界面中执行许多不同的操作。

    Here is what a sample job definition looks like, you can see it has a list of initiators defined at the top, and then a list of adapters/tasks defined after. You can also see, that the initiators can take parameters to allow them to do even more. This sample job definition is known as a jobspec.

    这是一个示例作业定义的样子,您可以看到它在顶部定义了一个initiators列表,然后在其后定义了一个adapters / tasks列表。 您还可以看到,启动器可以使用参数来允许它们做更多的事情。 此示例作业定义称为jobspec 。

    { "initiators": [ { "type": "runlog", "params": { "address": "0xd8c819674b79c7372d56db03280a5695a9254894" } } ], "tasks": [ { "type": "httpget" }, { "type": "jsonparse" }, { "type": "multiply" }, { "type": "ethuint256" }, { "type": "ethtx" } ]}

    Most nodes have a lot of similar jobs, and the one in the sample above is one of the most common jobs out there. This jobspec defines how to make simple httpget requests into your smart contract. There is also an httppost adapter if you’d like to make a POST request instead of a GET. This job is defined by a:

    大多数节点都有很多类似的作业,而上面示例中的节点是最常见的作业之一。 该工作规范定义了如何将简单的httpget请求发送到智能合约中。 如果您要发出POST请求而不是GET,则还有一个httppost适配器。 这项工作的定义是:

    Runlog initiator

    Runlog启动器

    This specific list of adapters/tasks: httpget, jsonparse, multiply, ethuint256, and ethTx adapters.

    适配器/任务的特定列表:httpget,jsonparse,multiple,ethuint256和ethTx适配器。

    The Runlog initiator is one of the most common initiators used. It defines that the chainlink node will watch the blockchain for any log events that include that job’s ID. Once it finds an event, it will execute the adapters, and post the data on-chain. We will go over what each one of these adapters does soon.

    Runlog启动器是最常用的启动器之一。 它定义了chainlink节点将监视区块链以查找包含该作业的ID的任何日志事件。 找到事件后,它将执行适配器,并将数据发布到链上。 我们将很快介绍每个适配器的功能。

    Your smart contract will have to wait a little for the Chainlink node to return your data, but once it does, your smart contract will pull the data from this transaction.

    您的智能合约将不得不稍等片刻,以便Chainlink节点返回您的数据,但是一旦发送,您的智能合约就会从该交易中提取数据。

    chain.link chain.link的图片

    牢固地看起来像什么? (What Does This Look Like in Solidity?)

    To show what this looks like in code, let’s look at getting the numerical price of ETH. You can use this Remix link to follow along, but here is a subset of that contract code.

    为了显示代码中的内容,让我们看一下获得ETH的价格。 您可以使用此Remix链接进行后续操作,但这是该合同代码的一部分。

    // Creates a Chainlink request with the uint256 multiplier job // Ideally, you'd want to pass the oracle payment, address, and jobID as function requestEthereumPrice() public onlyOwner { // newRequest takes a JobID, a callback address, and callback function as input Chainlink.Request memory req = buildChainlinkRequest(JOBID, address(this), this.fulfill.selector); req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD"); req.add("path", "USD"); req.addInt("times", 100); sendChainlinkRequestTo(ORACLE_ADDRESS, req, ORACLE_PAYMENT); }// fulfill receives a uint256 data type function fulfill(bytes32 _requestId, uint256 _price) public // Use recordChainlinkFulfillment to ensure only the requesting oracle can fulfill recordChainlinkFulfillment(_requestId) { currentPrice = _price; }

    To start making a request to a chainlink node, we call the buildChainlinkRequest function that is imported from the ChainlinkClient.sol, this function returns a Chainlink.Request struct. In this function, we pass the jobID, return address, and fulfillment function when we start to build it.

    要开始向buildChainlinkRequest节点发出请求,我们调用从buildChainlinkRequest导入的ChainlinkClient.sol函数,该函数返回Chainlink.Request结构。 在此函数中,当我们开始构建它时,我们传递了jobID,返回地址和履行函数。

    We can find a jobID of an independent Chainlink node by heading over to a node listing service, like market.link, and searching for what we want. Node listing services are where independent nodes post their information about how to connect to their Chainlink node. You can use them to build your network of decentralized oracles. Make sure you’re on the correct network (ropsten, mainnet, kovan, etc).

    通过转到节点列表服务(例如market.link )并搜索所需内容,我们可以找到独立的Chainlink节点的jobID。 节点列表服务是独立节点发布有关如何连接到其Chainlink节点的信息的地方。 您可以使用它们来构建分散的预言网络。 确保您使用的是正确的网络(ropsten,mainnet,kovan等)。

    For this, we want a job that can make an httpget call and return a uint256 , so let’s try searching for that job on the ropsten network.

    为此,我们需要一个可以进行httpget调用并返回uint256 ,因此让我们尝试在ropsten网络上搜索该作业。

    market.link market.link上寻找工作

    Let’s pick a job, and just make sure that the jobspec is what we are looking for. We can head on over to the jobspec tab to see what the initiators and adapters are.

    让我们选择一份工作,然后确保要找到的工作jobspec就是我们想要的。 我们可以转到jobspec选项卡以查看启动器和适配器是什么。

    market.link market.link

    To make sure this job has the right adapters, we can check out their tasks/adapters list. The image above shows that this job has exactly the initiators and adapters/tasks that we want.

    为确保此作业具有正确的适配器,我们可以查看其任务/适配器列表。 上图显示该作业恰好具有我们想要的启动器和适配器/任务。

    Once we verify that the job has the adapters we want, we can then copy the job ID to use in our code. You can see other nodes that have a similar job, and you’ll need this list when you make your contract decentralized, but again for testing and developing we can just pull from a single node. Make sure you also grab the oracle address, as you’ll need this later.

    一旦确认作业具有所需的适配器,我们就可以复制作业ID以在代码中使用。 您可以看到其他具有相似工作的节点,并且在分散合同时将需要此列表,但是再次进行测试和开发时,我们可以从单个节点提取。 确保您还获取了oracle地址,因为稍后将需要它。

    Chainlink.Request memory req = buildChainlinkRequest(JOBID, address(this), this.fulfill.selector);

    We then put the JOBID in the first parameter of our buildChainlinkReqeust. The second parameter is the address of the contract to return the data to also known as the callbackaddress. The last parameter is the function that will process the data once collected aka thecallbackFunctionSignature. We want to return the data to this contract, so we put in address(this), and our function that will be processing the data will be fulfill. We defined the fulfill function right below this one.

    然后,将JOBID放入buildChainlinkReqeust的第一个参数中。 第二个参数是将数据返回到的合同的地址,也称为callbackaddress 。 最后一个参数是将处理数据的函数,该数据又称为callbackFunctionSignature 。 我们希望将数据返回到这个合同,所以我们把address(this) ,和我们的函数将要处理的数据将fulfill 。 我们在此函数的下面定义了功能。

    function fulfill(bytes32 _requestId, uint256 _price) public // Use recordChainlinkFulfillment to ensure only the requesting oracle can fulfill recordChainlinkFulfillment(_requestId) { currentPrice = _price; }

    The uint256 _price parameter is where the Chainlink node will input the price gathered from making the http get request. In our example above, we are just setting the return value from the node to our currentPrice variable.

    uint256 _price参数是Chainlink节点将输入从发出http get请求收集的价格的位置。 在上面的示例中,我们只是将节点的返回值设置为currentPrice变量。

    Back in the requestEthereumPrice function, we can then add parameters to our adatpers/tasks. Let’s go over what each adapter does:

    回到requestEthereumPrice函数,然后我们可以向adatpers /任务添加参数。 让我们看一下每个适配器的作用:

    httpget (httpget)

    The Chainlink node will make an HTTP GET request; usually, this is a simple API call.

    Chainlink节点将发出HTTP GET请求; 通常,这是一个简单的API调用。

    The HTTP GET request that we want to make in the parameters passed to the req variable.

    我们要在传递给req变量的参数中发出的HTTP GET请求。

    req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");

    At the time of writing, the return value of this HTTP GET request is:

    在撰写本文时,此HTTP GET请求的返回值为:

    {"USD":391.41}

    jsonparse (jsonparse)

    Once the node makes the HTTP GET request, it will go through the json and find only the value that we want. Storing the entire return of the HTTP GET request would be really expensive, as the more you store on the Ethereum chain the more ETH gas you have to pay. So, we want to return as little as possible.

    节点发出HTTP GET请求后,它将遍历json并仅找到所需的值。 存储HTTP GET请求的整个返回将非常昂贵,因为您在以太坊链上存储的越多,您必须支付的ETH气体就越多。 因此,我们希望尽可能少地返回。

    req.add("path", "USD");

    This will condense the return of the HTTP GET request to just the value391.41 . It walks down the json of the {“USD”:391.41} return value. For longer json returns, you can add indexes of lists too. For example, if you had an object like:

    这会将HTTP GET请求的返回压缩为仅391.41的值。 它沿着{“USD”:391.41}返回值的json {“USD”:391.41} 。 对于更长的json返回,您也可以添加列表的索引。 例如,如果您有一个对象,例如:

    {"USD": [ "price": {"ETH": 391.41}]}

    We could walk down the path to that value with:

    我们可以通过以下方式实现这一价值:

    req.add("path", "USD.0.ETH");

    乘/次 (multiply/times)

    Once we get the 391.41 value, we have to make it a whole number. Decimals don’t work in solidity, and we need to represent decimals using fixed-point math.

    一旦获得391.41值,就必须将其设为整数。 小数不能可靠地起作用,我们需要使用定点数学来表示小数。

    req.addInt("times", 100);

    This will adapt our result once more to be 39141 (since we move the decimal place over twice by multiplying by 100).

    这将使我们的结果再次变为39141 (因为我们将小数点后两位乘以100移了两次)。

    256位 (ethuint256)

    You’ll notice in our code above, we don’t pass any parameters to this adapter; that’s because we don’t need to. This adapter just converts our answer of 39141 to the solidity understandable format.

    您会在上面的代码中注意到,我们没有将任何参数传递给此适配器; 那是因为我们不需要。 该适配器只是将我们对39141的回答转换为39141的固体格式。

    伦理 (ethtx)

    This one also doesn’t need any parameters. This is the adapter that actually posts the data back on-chain.

    这个也不需要任何参数。 这是实际将数据发布回链上的适配器。

    Now we use the sendChainlinkRequestTo method, with the address of the oracle we got from market.link, the request itself, and the oracle_payment.

    现在,我们使用sendChainlinkRequestTo方法,以及从sendChainlinkRequestTo的oracle的地址,请求本身和oracle_payment。

    sendChainlinkRequestTo(ORACLE_ADDRESS, req, ORACLE_PAYMENT);

    We get the ORACLE_ADDRESS and ORACLE_PAYMENT from market.link as well. The Oracle payment is how much LINK oracle gas we want to send the oracle, each job has its own minimum cost to send.

    我们得到的ORACLE_ADDRESS和ORACLE_PAYMENT从market.link为好。 Oracle的付款是我们要向Oracle发送多少LINK Oracle气体,每个作业都有其自己的最低发送成本。

    发送 (Send It)

    Now, let’s run it again! Let’s deploy the contract, fund it with link, and then request the price of ETH. You can go through the example walkthrough if you’re confused about how to do this. Or the more step-by-step YouTube video:

    现在,让我们再次运行它! 让我们部署合同,通过链接为其提供资金,然后请求ETH的价格。 如果您对如何执行操作感到困惑,则可以遍历示例演练 。 或更多分步的YouTube视频:

    Intro to Solidity and Remix and Deploy your first smart contract 介绍Solidity并重新混合和部署您的第一个智能合约

    The Chainlink node will pick up on the request by reading it off the blockchain. Again, it can read it off the blockchain because it is using the Runlog initiator. Once it picks up the job, it runs through the adapters, and posts it back on-chain for your smart contract to use!

    Chainlink节点将通过读取区块链来接收请求。 同样,它可以从区块链中读取它,因为它使用的是Runlog启动器。 一旦完成任务,它将运行在适配器中,然后将其重新发布到链上供您的智能合约使用!

    Oracles can define the parameters right in their job definitions as well (called the jobspec), and you could just call the job without having to put in any parameters at all.

    Oracle也可以在其作业定义中正确定义参数(称为jobspec ),您可以直接调用作业,而不必输入任何参数。

    This has been a pretty deep dive on exactly how working with Chainlink nodes work, but with this, you now have a lot of the basic tools to build some amazing projects in the blockchain ecosystem.

    这是对使用Chainlink节点的确切工作方式的深入探讨,但是有了这个,您现在有了许多基本工具,可以在区块链生态系统中构建一些出色的项目。

    If you haven’t already, this is your chance to take what you’ve learned, and put it to action. Be sure to join the Chainlink Hackathon; beginners and advanced engineers are all welcome!

    如果您还没有这样做,那么这是您采取所学知识并将其付诸实践的机会。 确保参加Chainlink Hackathon ; 欢迎初学者和高级工程师!

    翻译自: https://medium.com/better-programming/making-http-requests-in-solidity-b472c2b5e5f1

    基础不牢固地洞山摇

    相关资源:2020最新版林地承包合同范文3篇_精选.doc
    Processed: 0.009, SQL: 8