Skip to content

Commit

Permalink
feat: make BtcScript a library
Browse files Browse the repository at this point in the history
  • Loading branch information
reednaa committed Feb 25, 2024
1 parent 4eed319 commit 58ba758
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
22 changes: 11 additions & 11 deletions src/library/BtcScript.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ struct BitcoinAddress {
* when they encode or decode Bitcoin scripts.
* @dev This contract is not intended for on-chain calls.
*/
contract BtcScript {
library BtcScript {

//--- Bitcoin Script Decode Helpers ---//

/**
* @notice Global helper for decoding Bitcoin addresses
*/
function getBitcoinAddress(bytes calldata script) external pure returns(BitcoinAddress memory btcAddress) {
function getBitcoinAddress(bytes calldata script) internal pure returns(BitcoinAddress memory btcAddress) {
// Check if P2PKH
bytes1 firstByte = script[0];
if (firstByte == OP_DUB) {
Expand Down Expand Up @@ -72,7 +72,7 @@ contract BtcScript {
* @return hash The recipient script hash, or 0 if verification failed.
*/
function decodeP2SH(bytes calldata script)
public
internal
pure
returns (bytes20)
{
Expand All @@ -91,7 +91,7 @@ contract BtcScript {
* @return hash The recipient public key hash, or 0 if verification failed.
*/
function decodeP2PKH(bytes calldata script)
public
internal
pure
returns (bytes20)
{
Expand All @@ -112,7 +112,7 @@ contract BtcScript {
* @return witPro The witness program, or nothing if verification failed.
*/
function decodeWitnessProgram(bytes calldata script)
public
internal
pure
returns (int8 version, uint8 witnessLength, bytes32 witPro)
{
Expand Down Expand Up @@ -144,7 +144,7 @@ contract BtcScript {
/**
* @notice Global helper for encoding Bitcoin scripts
*/
function getBitcoinScript(BitcoinAddress calldata btcAddress) external pure returns(bytes memory script) {
function getBitcoinScript(BitcoinAddress calldata btcAddress) internal pure returns(bytes memory script) {
// Check if segwit
if (btcAddress.addressType == AddressType.P2PKH) return scriptP2PKH(bytes20(btcAddress.implementationHash));
if (btcAddress.addressType == AddressType.P2SH) return scriptP2SH(bytes20(btcAddress.implementationHash));
Expand All @@ -160,27 +160,27 @@ contract BtcScript {
}

/// @notice Get the associated script out for a P2PKH address
function scriptP2PKH(bytes20 pHash) public pure returns(bytes memory) {
function scriptP2PKH(bytes20 pHash) internal pure returns(bytes memory) {
// OP_DUB, OP_HASH160, <pubKeyHash 20>, OP_EQUALVERIFY, OP_CHECKSIG
return bytes.concat(OP_DUB, OP_HASH160, PUSH_20, pHash, OP_EQUALVERIFY, OP_CHECKSIG);
}

/// @notice Get the associated script out for a P2SH address
function scriptP2SH(bytes20 sHash) public pure returns(bytes memory) {
function scriptP2SH(bytes20 sHash) internal pure returns(bytes memory) {
// OP_HASH160, <data 20>, OP_EQUAL
return bytes.concat(OP_HASH160, PUSH_20, sHash, OP_EQUAL);
}

function scriptP2WPKH(bytes20 witnessProgram) public pure returns(bytes memory) {
function scriptP2WPKH(bytes20 witnessProgram) internal pure returns(bytes memory) {
// OP_0, <data 20>
return bytes.concat(OP_0, PUSH_20, witnessProgram);
}

function scriptP2WSH(bytes32 witnessProgram) public pure returns(bytes memory) {
function scriptP2WSH(bytes32 witnessProgram) internal pure returns(bytes memory) {
return bytes.concat(OP_0, PUSH_32, witnessProgram);
}

function scriptP2TR(bytes32 witnessProgram) public pure returns(bytes memory) {
function scriptP2TR(bytes32 witnessProgram) internal pure returns(bytes memory) {
return bytes.concat(OP_0, PUSH_32, witnessProgram);
}
}
14 changes: 8 additions & 6 deletions test/BtcScript.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ import "forge-std/Test.sol";

import { BtcScript} from "../src/library/BtcScript.sol";

contract BtcProofTest is DSTest, BtcScript {

BtcScript btcScript = new BtcScript();
contract BtcProofTest is DSTest {

function testGetP2SH() public {
bytes memory validP2SH = hex"a914ae2f3d4b06579b62574d6178c10c882b9150374087";
bytes memory invalidP2SH1 = hex"a914ae2f3d4b06579b62574d6178c10c882b9150374086";
bytes memory invalidP2SH2 = hex"a900ae2f3d4b06579b62574d6178c10c882b9150374087";

assertEq(
uint160(btcScript.decodeP2SH(validP2SH)),
uint160(this.decodeP2SH(validP2SH)),
0x00ae2f3d4b06579b62574d6178c10c882b91503740
);

assertEq(uint160(btcScript.decodeP2SH(invalidP2SH1)), 0);
assertEq(uint160(btcScript.decodeP2SH(invalidP2SH2)), 0);
assertEq(uint160(this.decodeP2SH(invalidP2SH1)), 0);
assertEq(uint160(this.decodeP2SH(invalidP2SH2)), 0);
}

function decodeP2SH(bytes calldata P2SH) external pure returns(bytes20) {
return BtcScript.decodeP2SH(P2SH);
}
}

0 comments on commit 58ba758

Please sign in to comment.