Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/BitcoinUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ library BitcoinUtils {

string constant BECH32_ALPHABET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";

function BECH32_ALPHABET_MAP(bytes1 char) public view returns (uint8) {
function BECH32_ALPHABET_MAP(bytes1 char) internal view returns (uint8) {
// '{"0":15,"2":10,"3":17,"4":21,"5":20,"6":26,"7":30,"8":7,"9":5,"q":0,"p":1,"z":2,"r":3,"y":4,"x":6,"g":8,"f":9,"t":11,"v":12,"d":13,"w":14,"s":16,"j":18,"n":19,"k":22,"h":23,"c":24,"e":25,"m":27,"u":28,"a":29,"l":31}'

if (char == bytes1("0")) return 15;
Expand Down Expand Up @@ -73,7 +73,7 @@ library BitcoinUtils {
function validateBitcoinAddress(
BitcoinNetworkEncoder.Network network,
string calldata BTCAddress
) public view returns (bool)
) internal view returns (bool)
{
bytes memory empty;

Expand Down Expand Up @@ -110,7 +110,7 @@ library BitcoinUtils {
return false;
}

function equalBytes(bytes memory one, bytes memory two) public pure returns (bool) {
function equalBytes(bytes memory one, bytes memory two) internal pure returns (bool) {
if (!(one.length == two.length)) {
return false;
}
Expand All @@ -122,7 +122,7 @@ library BitcoinUtils {
return true;
}

function alphabetCheck(bytes memory BTCAddress) public pure returns (bool) {
function alphabetCheck(bytes memory BTCAddress) internal pure returns (bool) {
uint256 BTCAddressLength = BTCAddress.length;
for (uint256 i = 0; i < BTCAddressLength; ++i) {
uint8 charCode = uint8(BTCAddress[i]);
Expand Down Expand Up @@ -150,7 +150,7 @@ library BitcoinUtils {
}

// This function supports both bech32 (SegWit v0) and bech32m (Taproot/SegWit v1) addresses
function validateBech32Checksum(string memory btcAddress) public view returns (bool) {
function validateBech32Checksum(string memory btcAddress) internal view returns (bool) {
console.log("\nvalidate bech32 checksum");
console.log("address");
console.log(btcAddress);
Expand Down Expand Up @@ -254,7 +254,7 @@ library BitcoinUtils {
return true;
}

function polymodStep(uint256 pre) public pure returns (uint256) {
function polymodStep(uint256 pre) internal pure returns (uint256) {
uint256 b = pre >> 25;

return (
Expand All @@ -264,7 +264,7 @@ library BitcoinUtils {
);
}

function prefixChk(bytes memory prefix) public pure returns (uint256) {
function prefixChk(bytes memory prefix) internal pure returns (uint256) {
uint256 chk = 1;
uint256 prefixLength = bytes(prefix).length;
for (uint256 i = 0; i < prefixLength; ++i) {
Expand All @@ -283,7 +283,7 @@ library BitcoinUtils {
return chk;
}

function validateBase58Checksum(string calldata btcAddress) public view returns (bool) {
function validateBase58Checksum(string calldata btcAddress) internal view returns (bool) {
bytes memory rawData = decodeFromString(btcAddress);

console.log("validateBase58Checksum");
Expand Down
33 changes: 21 additions & 12 deletions test/BitcoinUtils_Mainnet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,42 @@ contract BitcoinUtils_Mainnet_Test is Test {
using BitcoinUtils for BitcoinNetworkEncoder.Network;
BitcoinNetworkEncoder.Network private network = BitcoinNetworkEncoder.Network.Mainnet;

// Helper function to convert memory to calldata
function _validate(string memory addr) private view returns (bool) {
return this._validateCalldata(addr);
}

function _validateCalldata(string calldata addr) external view returns (bool) {
return network.validateBitcoinAddress(addr);
}

function testValidAddress() public view {
assertTrue(network.validateBitcoinAddress("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"));
assertTrue(network.validateBitcoinAddress("15hPYnf4qXCbDBi96DsUPdZ34RyZ5Lou1a"));
assertTrue(_validate("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"));
assertTrue(_validate("15hPYnf4qXCbDBi96DsUPdZ34RyZ5Lou1a"));
}

function testInvalidAddress() public view {
assertFalse(network.validateBitcoinAddress(""));
assertFalse(network.validateBitcoinAddress("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(network.validateBitcoinAddress("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
assertFalse(_validate(""));
assertFalse(_validate("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(_validate("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
}

function testBech32ValidAddress() public view {
assertTrue(network.validateBitcoinAddress("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertTrue(network.validateBitcoinAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
assertTrue(_validate("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertTrue(_validate("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
}

function testBech32InvalidAddress() public view {
assertFalse(network.validateBitcoinAddress("BC1SW50QA3JX3S"));
assertFalse(_validate("BC1SW50QA3JX3S"));

// wrong encoding
assertFalse(network.validateBitcoinAddress("bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du"));
assertFalse(_validate("bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du"));

// invalid checksum
assertFalse(network.validateBitcoinAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5"));
assertFalse(_validate("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5"));

assertFalse(network.validateBitcoinAddress("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7"));
assertFalse(_validate("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7"));

assertFalse(network.validateBitcoinAddress("tb1pw508d6qejxtdg4y5r3zarquvzkan"));
assertFalse(_validate("tb1pw508d6qejxtdg4y5r3zarquvzkan"));
}
}
27 changes: 18 additions & 9 deletions test/BitcoinUtils_Regtest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,33 @@ contract BitcoinUtils_Regtest_Test is Test {
using BitcoinUtils for BitcoinNetworkEncoder.Network;
BitcoinNetworkEncoder.Network private network = BitcoinNetworkEncoder.Network.Regtest;

// Helper function to convert memory to calldata
function _validate(string memory addr) private view returns (bool) {
return this._validateCalldata(addr);
}

function _validateCalldata(string calldata addr) external view returns (bool) {
return network.validateBitcoinAddress(addr);
}

function testValidAddress() public view {
assertTrue(network.validateBitcoinAddress("2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w"));
assertTrue(network.validateBitcoinAddress("mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"));
assertTrue(_validate("2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w"));
assertTrue(_validate("mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"));
}

function testInvalidAddress() public view {
assertFalse(network.validateBitcoinAddress(""));
assertFalse(network.validateBitcoinAddress("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(network.validateBitcoinAddress("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
assertFalse(_validate(""));
assertFalse(_validate("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(_validate("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
}

function testBech32ValidAddress() public view {
assertTrue(network.validateBitcoinAddress("bcrt1qnd2xm45v0uy5nx3qzt28qrhq42w4udrms8sz52"));
assertTrue(network.validateBitcoinAddress("bcrt1pnmrmugapastum8ztvgwcn8hvq2avmcwh2j4ssru7rtyygkpqq98q4wyd6s"));
assertTrue(_validate("bcrt1qnd2xm45v0uy5nx3qzt28qrhq42w4udrms8sz52"));
assertTrue(_validate("bcrt1pnmrmugapastum8ztvgwcn8hvq2avmcwh2j4ssru7rtyygkpqq98q4wyd6s"));
}

function testBech32ValidMainnetAddressIsNotValidForRegtest() public view {
assertFalse(network.validateBitcoinAddress("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(network.validateBitcoinAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
assertFalse(_validate("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(_validate("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
}
}
27 changes: 18 additions & 9 deletions test/BitcoinUtils_Simnet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,33 @@ contract BitcoinUtils_Simnet_Test is Test {
using BitcoinUtils for BitcoinNetworkEncoder.Network;
BitcoinNetworkEncoder.Network private network = BitcoinNetworkEncoder.Network.Simnet;

// Helper function to convert memory to calldata
function _validate(string memory addr) private view returns (bool) {
return this._validateCalldata(addr);
}

function _validateCalldata(string calldata addr) external view returns (bool) {
return network.validateBitcoinAddress(addr);
}

function testValidAddress() public view {
assertTrue(network.validateBitcoinAddress("ScuV2eqXfQCPcpxqqVSFtMVwkfqcwnQKB1"));
assertTrue(network.validateBitcoinAddress("SYi7rot5GKoyuRNUnjrfKYRBL7F4e9L8bN"));
assertTrue(_validate("ScuV2eqXfQCPcpxqqVSFtMVwkfqcwnQKB1"));
assertTrue(_validate("SYi7rot5GKoyuRNUnjrfKYRBL7F4e9L8bN"));
}

function testInvalidAddress() public view {
assertFalse(network.validateBitcoinAddress(""));
assertFalse(network.validateBitcoinAddress("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(network.validateBitcoinAddress("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
assertFalse(_validate(""));
assertFalse(_validate("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(_validate("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
}

function testBech32ValidAddress() public view {
assertTrue(network.validateBitcoinAddress("sb1p5z8wl5tu7m0d79vzqqsl9gu0x4fkjug857fusx4fl4kfgwh5j25sxv5dv3"));
assertTrue(network.validateBitcoinAddress("sb1pfusykjdt46ktwq03d20uqqf94uh9487344wr3q5v9szzsxnjdfkszvtlt8"));
assertTrue(_validate("sb1p5z8wl5tu7m0d79vzqqsl9gu0x4fkjug857fusx4fl4kfgwh5j25sxv5dv3"));
assertTrue(_validate("sb1pfusykjdt46ktwq03d20uqqf94uh9487344wr3q5v9szzsxnjdfkszvtlt8"));
}

function testBech32ValidMainnetAddressIsNotValidForTestnet() public view {
assertFalse(network.validateBitcoinAddress("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(network.validateBitcoinAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
assertFalse(_validate("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(_validate("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
}
}
29 changes: 19 additions & 10 deletions test/BitcoinUtils_Testnet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,35 @@ import "../src/BitcoinNetworkEncoder.sol";
contract BitcoinUtils_Testnet_Test is Test {
using BitcoinUtils for BitcoinNetworkEncoder.Network;
BitcoinNetworkEncoder.Network private network = BitcoinNetworkEncoder.Network.Testnet;

// Helper function to convert memory to calldata
function _validate(string memory addr) private view returns (bool) {
return this._validateCalldata(addr);
}

function _validateCalldata(string calldata addr) external view returns (bool) {
return network.validateBitcoinAddress(addr);
}

function testValidAddress() public view {
assertTrue(network.validateBitcoinAddress("2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w"));
assertTrue(network.validateBitcoinAddress("mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"));
assertTrue(network.validateBitcoinAddress("2NFPLS6TQVVvic6Nh85PGfcYesbGdm1fjpo"));
assertTrue(_validate("2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w"));
assertTrue(_validate("mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"));
assertTrue(_validate("2NFPLS6TQVVvic6Nh85PGfcYesbGdm1fjpo"));
}

function testInvalidAddress() public view {
assertFalse(network.validateBitcoinAddress(""));
assertFalse(network.validateBitcoinAddress("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(network.validateBitcoinAddress("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
assertFalse(_validate(""));
assertFalse(_validate("7SeEnXWPaCCALbVrTnszCVGfRU8cGfx"));
assertFalse(_validate("j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe"));
}

function testBech32ValidAddress() public view {
assertTrue(network.validateBitcoinAddress("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"));
assertTrue(network.validateBitcoinAddress("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"));
assertTrue(_validate("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"));
assertTrue(_validate("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"));
}

function testBech32ValidMainnetAddressIsNotValidForTestnet() public view {
assertFalse(network.validateBitcoinAddress("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(network.validateBitcoinAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
assertFalse(_validate("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"));
assertFalse(_validate("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"));
}
}