Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Dapp-Learning-DAO/Dapp-Learning
Browse files Browse the repository at this point in the history
  • Loading branch information
luna2163 committed Nov 2, 2024
2 parents 2baf920 + f5a093a commit f328e70
Show file tree
Hide file tree
Showing 29 changed files with 922 additions and 431 deletions.
46 changes: 46 additions & 0 deletions BTC/Advanced/OP_CAT/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
`OP_CAT` 是比特币脚本中的一个操作码(opcode),它用于将两个或多个元素连接在一起。这一功能在比特币的原生脚本语言中并不存在,因此 `OP_CAT` 的引入是为了增强比特币脚本的灵活性和功能,特别是在智能合约和复杂交易的应用场景中。

### `OP_CAT` 的背景和用途

1. **操作码(Opcode)概述**
- 比特币的脚本语言是栈式的,操作码是脚本的基本组成部分。每个操作码执行特定的功能,如加法、签名验证和数据操作等。
- `OP_CAT` 用于将两个栈顶元素连接(concatenate)成一个更大的元素。这对于构建复杂数据结构和处理更复杂的脚本逻辑非常有用。

2. **为何需要 `OP_CAT`**
- 在比特币早期的脚本语言中,没有直接的连接字符串或数据的功能。这限制了某些智能合约和复杂交易的实现。
- 引入 `OP_CAT` 使得开发者能够更灵活地操作和组合数据,增强了比特币脚本的表达能力。

### `OP_CAT` 的功能

- **连接功能**`OP_CAT` 将两个元素从栈中取出,并将它们连接成一个新的元素。举例来说,如果栈顶的元素是字符串 "Hello" 和 "World",执行 `OP_CAT` 后,栈顶元素将变成 "HelloWorld"。
- **应用场景**
- **智能合约**:在构建智能合约时,可以利用 `OP_CAT` 组合数据,形成更复杂的数据结构。
- **多签名交易**:在多签名场景中,可以将多个公钥或签名连接在一起,以便在验证时进行处理。
- **数据打包**:当需要将多个输入数据合并成一个输出时,`OP_CAT` 是一个重要工具。

### 示例

假设我们有两个元素在栈中,分别为 "Data1" 和 "Data2"。使用 `OP_CAT` 的过程如下:

1. **栈状态**
```
Top -> Data2
Data1
```

2. **执行 `OP_CAT`**
- 栈顶的两个元素 "Data1" 和 "Data2" 被取出,并连接在一起。

3. **结果栈状态**
```
Top -> Data1Data2
```

### 安全性和实现

- **安全性**:虽然 `OP_CAT` 增强了脚本的灵活性,但也可能引入一些复杂性。合约的开发者需要确保合约逻辑的安全性和正确性,避免潜在的漏洞。
- **实现**`OP_CAT` 的实现需要对比特币的脚本引擎进行修改,因此需要在比特币核心代码中进行添加和测试,确保它与现有的操作码兼容。

### 结论

`OP_CAT` 的引入为比特币的脚本语言增加了重要的功能,使得在智能合约和复杂交易的开发中可以更灵活地处理数据。尽管比特币的脚本设计注重安全性和简单性,但通过引入 `OP_CAT`,开发者能够实现更丰富的逻辑和应用场景。随着比特币生态系统的发展,像 `OP_CAT` 这样的操作码可能会变得越来越重要。
60 changes: 60 additions & 0 deletions BTC/Advanced/OP_CAT/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
你是对的,我在之前的示例中没有明确给出与 `OP_EQUAL` 验证的内容。在比特币脚本中,`OP_EQUAL` 用于验证栈顶两个元素是否相等。因此,我们需要在脚本中明确指定连接后的结果,并与这个结果进行比较。

### 完整示例

下面是一个更新后的示例,展示如何使用 `OP_CAT` 实现智能合约,并在脚本中验证连接后的结果是否等于 "HelloWorld":

```javascript
const bitcoin = require('bitcoinjs-lib');

// 创建一个包含 OP_CAT 的脚本
function createScript() {
// 连接的目标结果
const target = Buffer.from('HelloWorld');

const script = bitcoin.script.compile([
bitcoin.opcodes.OP_DUP,
bitcoin.opcodes.OP_HASH160,
Buffer.from('...'), // 使用适当的公钥哈希
bitcoin.opcodes.OP_EQUALVERIFY,
bitcoin.opcodes.OP_CHECKSIG,
// 连接两个字符串
Buffer.from('Hello'), // 第一个元素
Buffer.from('World'), // 第二个元素
bitcoin.opcodes.OP_CAT, // 连接操作
target, // 连接后的目标结果
bitcoin.opcodes.OP_EQUAL // 验证连接结果是否等于 'HelloWorld'
]);

return script;
}

// 创建和打印 P2SH 地址
function createP2SHAddress() {
const script = createScript();
const { address } = bitcoin.payments.p2sh({ redeem: { output: script, network: bitcoin.networks.bitcoin } });

console.log('P2SH Address:', address);
}

createP2SHAddress();
```

### 代码解析

1. **连接后的目标结果**
- 我们定义了一个 `target` 变量,表示连接后的目标结果 `HelloWorld`。在脚本中,我们将这个目标结果与连接后的结果进行比较。

2. **脚本逻辑**
- `OP_CAT``Buffer.from('Hello')``Buffer.from('World')` 连接起来,结果是 `HelloWorld`
- 然后,`target`(即 `HelloWorld`)被推入栈中。
- 最后,`OP_EQUAL` 用于检查连接的结果是否与 `target` 相等。

### 注意事项

- **脚本验证**:在比特币的环境中,脚本通常是在执行交易时被验证。因此,这段脚本需要在合适的环境中进行测试。
- **公钥哈希**:在实际应用中,`Buffer.from('...')` 应替换为实际的公钥哈希。

### 结论

现在这个脚本清楚地验证了连接后的结果是否与预期值 `HelloWorld` 相等。这种方式展示了如何在比特币脚本中使用 `OP_CAT` 进行数据连接和验证。虽然比特币的脚本语言有一定的限制,但通过合理组合操作码,依然可以实现复杂的逻辑。
33 changes: 33 additions & 0 deletions BTC/Advanced/OP_CAT/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const bitcoin = require('bitcoinjs-lib');

// 创建一个包含 OP_CAT 的脚本
function createScript() {
// 连接的目标结果
const target = Buffer.from('HelloWorld');

const script = bitcoin.script.compile([
bitcoin.opcodes.OP_DUP,
bitcoin.opcodes.OP_HASH160,
Buffer.from('...'), // 使用适当的公钥哈希
bitcoin.opcodes.OP_EQUALVERIFY,
bitcoin.opcodes.OP_CHECKSIG,
// 连接两个字符串
Buffer.from('Hello'), // 第一个元素
Buffer.from('World'), // 第二个元素
bitcoin.opcodes.OP_CAT, // 连接操作,必须在两个字符串之后
target, // 连接后的目标结果
bitcoin.opcodes.OP_EQUAL // 验证连接结果是否等于 'HelloWorld'
]);

return script;
}

// 创建和打印 P2SH 地址
function createP2SHAddress() {
const script = createScript();
const { address } = bitcoin.payments.p2sh({ redeem: { output: script, network: bitcoin.networks.bitcoin } });

console.log('P2SH Address:', address);
}

createP2SHAddress();
8 changes: 5 additions & 3 deletions basic/14-chainlink-price-feed/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
PRIVATE_KEY=xxxxxxxxxxxxxxxx
INFURA_ID=yyyyyyyy
SubscriptionId=ddddd
PRIVATE_KEY=xxxx
PUBLIC_ADDRESS=xxxx
MNEMONIC=xxxx
API_KEY=xxxx
SubscriptionId=xxxx
47 changes: 16 additions & 31 deletions basic/14-chainlink-price-feed/contracts/PriceConsumerV3.sol
Original file line number Diff line number Diff line change
@@ -1,48 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import {AggregatorV3Interface} from '@chainlink/contracts/src/v0.8/shared/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.
*/
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";

contract PriceConsumerV3 {
AggregatorV3Interface internal dataFeed;

AggregatorV3Interface internal priceFeed;

/**
* Network: Sepolia
* Aggregator: BTC/USD
* Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
* Aggregator: ETH/USD
* Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306
*/
constructor(address _priceFeed) {
dataFeed = AggregatorV3Interface(_priceFeed);
priceFeed = AggregatorV3Interface(_priceFeed);
}

/**
* Returns the latest answer.
* Returns the latest price
*/
function getChainlinkDataFeedLatestAnswer() public view returns (int) {
// prettier-ignore
function getLatestPrice() public view returns (int) {
(
/* uint80 roundID */,
int answer,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = dataFeed.latestRoundData();
return answer;
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity 0.8.19;
pragma solidity ^0.8.7;

import {VRFConsumerBaseV2Plus} from '@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol';
import {VRFV2PlusClient} from '@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol';
Expand Down
66 changes: 16 additions & 50 deletions basic/14-chainlink-price-feed/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,32 @@
require("@nomiclabs/hardhat-waffle")
require("@nomiclabs/hardhat-ethers")
require("@nomiclabs/hardhat-web3")
require("@nomiclabs/hardhat-truffle5")
require("@nomiclabs/hardhat-etherscan");
require("hardhat-deploy")
const fs = require("fs");
require('dotenv').config()

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task('accounts', 'Prints the list of accounts', async () => {
const accounts = await ethers.getSigners();

for (const account of accounts) {
console.log(account.address);
}
});

function mnemonic () {

return process.env.PRIVATE_KEY
require("@nomicfoundation/hardhat-ethers");
require('dotenv').config({'path': './.env'});

function mnemonic() {
return process.env.PRIVATE_KEY;
}

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/

module.exports = {
defaultNetwork: "hardhat",
defaultNetwork: "sepolia",
networks: {
localhost: {
url: 'http://localhost:8545',
//gasPrice: 125000000000, // you can adjust gasPrice locally to see how much it will cost on production
/*
notice no mnemonic here? it will just use account 0 of the hardhat node to deploy
(you can put in a mnemonic here to set the deployer locally)
*/
hardhat: {
// // If you want to do some forking, uncomment this
// forking: {
// url: mainnetRpcUrl
// }
},
sepolia: {
url: 'https://sepolia.infura.io/v3/' + process.env.INFURA_ID, //<---- YOUR INFURA ID! (or it won't work)
url: 'https://eth-sepolia.g.alchemy.com/v2/' + process.env.API_KEY, //<---- YOUR alchemy ID! (or it won't work)
accounts: [mnemonic()],
ignition: {
maxFeePerGasLimit: 10_000_000_000_000n,
maxPriorityFeePerGas: 20_000_000_000n,
}
},
},
namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
1: 0 // similarly on mainnet it will take the first account as deployer. Note though that depending on how hardhat network are configured, the account 0 on one network can be different than on another
},
feeCollector: {
default: 1
}
},
solidity: {
compilers: [
{
version: "0.8.19"
version: "0.8.7"
}
]
},
Expand All @@ -69,5 +37,3 @@ module.exports = {
timeout: 6000000000000000
}
}


18 changes: 6 additions & 12 deletions basic/14-chainlink-price-feed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-truffle5": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@nomiclabs/hardhat-web3": "^2.0.0",
"chai": "^4.3.4",
"ethereum-waffle": "^3.3.0",
"ethers": "^5.7.2",
"hardhat": "^2.22.6",
"hardhat-deploy": "^0.7.9",
"web3": "^1.3.6"
"@chainlink/contracts": "^1.3.0",
"@nomicfoundation/hardhat-ethers": "^3.0.8",
"ethers": "^6.13.4",
"hardhat": "^2.22.13",
"dotenv": "^10.0.0"
},
"dependencies": {
"@chainlink/contracts": "^1.2.0",
"@nomiclabs/hardhat-etherscan": "^3.0.1",
"@chainlink/contracts": "^1.3.0",
"dotenv": "^10.0.0",
"moment": "^2.29.4"
}
Expand Down
Loading

0 comments on commit f328e70

Please sign in to comment.