了解区块链技术(Patrick Collins)(三)

发布于:2024-05-31 ⋅ 阅读:(78) ⋅ 点赞:(0)

3-1 通过函数发送ETH&返回

每当我们在任何一个兼容EVM的区块链上创建一笔交易时,Value代表将通过这笔交易发送多少ETH

我们发送的每笔交易,都会有:

Nonce:账户的交易序号
Gas Price   Gas  Limit
To:交易将要发送到的地址
Value:表示将要发送的数量
Data:如果在调用智能合约或者部署的时候就会发送它
v,r,s三个参数,交易签名时复杂的交易技术

ETH进制转换:eth-converter.com

为了使函数能够被ETH或者其他通证支付,需要将函数设置成Payable

钱包 可以持有资金,我们的合约地址也可以持有资金,每次部署合约时,都会获取一个合约地址

所有钱包和合约都可以持有像以太坊这样的原生区块链通证

我们希望在所有交易中至少转账一个以太币

require(msg.value > 1e18,"didn't send enough")   1*10**18
会检查关键字是否大于1,如果不是,它将revert这笔交易,同时显示错误信息
revert将之前的操作回滚,并将剩余的Gas费返回
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
contract FundMe {
    uint256 public number;
    function fund() public payable  {   
        number = 5 ;
        require(msg.value > 1e18,"didn't send enough") ;
    }
}

如果想要检查msg.value是否大于某个数量的法币

require(msg.value > minimumUsd,"didn't send enough") ;
单位不同,如何将以太币转换成USD呢 ?这就是预言机的作用
为了获取以太币的美元价格,我们需要从区块链之外获取信息返回到以太坊或其他原生智能合约平台,使用去中心化的预言机网络

区块链是确定性系统,所有节点需要达成共识,自身不能和现实世界的数据和事件进行交互,不知道任何信息,也不能做任何外部运算

如果想要添加可变数据或者随机数,或者调用API获取返回值,不同节点可能获取到不同结果,那么就永远不能达到共识,这被称为智能合约连接问题或者说预言机问题

区块链预言机是一种工具,他可以与世界交互,给智能合约提供外部数据或计算,Chainlink是一种去中心化的预言机网络,用于将数据和运算引入我们的智能合约。可定制以传输数据或者执行任何想要执行的外部计算。

Chainlink有大量去中心化的开箱即用的功能,随时集成到智能合约应用程序中。

data feed(喂价):Chainlink节点通过去中心化网络从不同的交易所或者数据提供商获取数据,Chainlink节点使用中位数来计算资产的价格,然后在单个交易中将其传递给参考合约、喂价合约或者链上数据合约,这些合约上的数据能被其他只能合约使用。

data.chain.link

https://docs.chain.link/data-feeds/using-data-feeds

在ETH/USD上,我们可以看到独立Chainlink节点运营商的网络,它们对ETH的价格有着不同的答案,这些价格会被网络聚合,然后在链上显示。Chainlink网络中每个节点都获取有关资产的信息,然后在交易中用自己的私钥进行签名,然后由一个节点将所有的签名的数据发送给相关合约,如果这一个节点不发送数据,则另一个节点代替它发送。Chainlink节点运营商的信誉非常重要,如果没有发送数据或者更新交易,会很快踢出网络并且不会有机会挣钱。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
​
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
​
/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED
 * VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */
​
/**
 * If you are reading data feeds on L2 networks, you must
 * check the latest answer from the L2 Sequencer Uptime
 * Feed to ensure that the data is accurate in the event
 * of an L2 sequencer outage. See the
 * https://docs.chain.link/data-feeds/l2-sequencer-feeds
 * page for details.
 */
​
contract DataConsumerV3 {
    AggregatorV3Interface internal dataFeed;
​
    /**
     * Network: Sepolia
     * Aggregator: BTC/USD
     * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
     */
     //数据是从Sepolia的喂价中获取的
    constructor() {
        dataFeed = AggregatorV3Interface(
            0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
        );
    }
​
    /**
     * Returns the latest answer.
     */
    function getChainlinkDataFeedLatestAnswer() public view returns (int) {
        // prettier-ignore
        (
            /* uint80 roundID */,
            int answer,
            /*uint startedAt*/,
            /*uint timeStamp*/,
            /*uint80 answeredInRound*/
        ) = dataFeed.latestRoundData();
        return answer;
    }
}
​

https://faucets.chain.link/获取一些Sepolia币,部署后会看到:

获得到的结果是:4265904368161 solidity中不能显示小数 $4265

JavaScript VM没有Chainlink节点

功能二:VRF,区块链是确定性系统,不具备随机性,我们需要通过区块链外部获取可验证的随机数,Chainlink可验证随机性函数是一种能将可证明的随机数放入智能合约中的方法,以保证公平性和应用程序的随机性。

在应用程序中获取一个可验证的随机数:

docs.chain.link/docs/get-a-random-number/

功能三:Chainlink Keepers可以以去中心化方式,通过event触发的函数执行,用于监听指定的不同触发时间的注册合约的Chainlink节点

功能四:Chainlink any API 可定制性,智能合约可以保证端到端的可靠性,我们希望并且需要它们能做任何事情,我们希望能够获取任意输入获取任何输出,通过HTTP GET和POST方法,定制Chainlink节点做任何事情。

https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&page=1

ETH/USD所对应的就是我们要使用的合约地址,使用的测试网络是Sepolia,0x694AA1769357215DE4FAC081bf1f309aDC325306

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
//(1)合约需要能从用户处获得资金
//(2)能够提取资金
//(3)设计一个以美元为最小单位的资助
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
    //最小Usd金额
    uint256 public minimumUsd = 50 ;
    function fund() public payable  {   
        //设置一个以USD计算的最小单元
        //如何想这个合约转ETH
        require(msg.value > minimumUsd,"didn't send enough") ;
    }
​
    // function withdraw() public{}
​
    // 创建一个函数获取价格以获取转换率,获取以美元为单位的价格函数
    function getPrice() public {
        //使用Chainlink喂价获取定价信息
        //合约ABI和项目地址   docs.chaiin.link/docs/etherum-address/
        //0x694AA1769357215DE4FAC081bf1f309aDC325306
    }
​
    function getVersion()public view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
        return priceFeed.version();
    }
    function getConversionRate() public {     
    }
}

结果:

代码直接从github中导入或者通过NPM包

remix能自动识别@chainlink/contracts就是指向Chainlink/contracts的NPM包

NPM包管理器,可以保留不同合约的版本,供我们直接导入代码中

Solidity的浮点数计算

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
//(1)合约需要能从用户处获得资金
//(2)能够提取资金
//(3)设计一个以美元为最小单位的资助
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
    //最小Usd金额
    uint256 public minimumUsd = 50 * 1e18 ;
    function fund() public payable  {   
        //设置一个以USD计算的最小单元
        //如何想这个合约转ETH,getConversionRate(msg.value)返回结果有18个零
        //计算以太坊的价格,3000多美金 相当于0.017eth,也就是17000000000000000
        require(getConversionRate(msg.value) > minimumUsd,"didn't send enough") ;
    }
​
    // function withdraw() public{}
​
    // 创建一个函数获取价格以获取转换率,获取以美元为单位的价格函数
    function getPrice() public view returns (uint256) {
        //使用Chainlink喂价获取定价信息
        //合约ABI和项目地址   docs.chaiin.link/docs/etherum-address/
        //0x694AA1769357215DE4FAC081bf1f309aDC325306
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
        // (uint80 roundId , int price , uint startAt , uint timeStamp , uint80 answerInRound) = priceFeed.latestRoundData();
        // 只关心价格(ETH关于USD的价格),所以
        (,int256 price,,,) = priceFeed.latestRoundData();
        //Solidity不能使用小数
        //想知道小数点后有多少位,调用decimal,会返回喂价返回的值中,有多少在小数点之后
        //一个eth是10的18次方wei,而price小数点后只有8个0,所以再向后面添加10个零
        return uint256(price*1e10);
​
    }
​
    function getVersion()public view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
        return priceFeed.version();
    }
    function getConversionRate(uint256 ethAmount) public view returns (uint256){
        uint256 ethPrice = getPrice();
        // 相乘后会有36位小数,想要的是18位小数
        uint256 ethAmountInUsd = (ethAmount * ethPrice)/1e18;
        return ethAmountInUsd ;  
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到