// encodePKAddress returns a human-readable payment address to a public key // given a serialized public key, a netID, and a signature suite. func encodePKAddress(serializedPK []byte, netID [2]byte, algo int) string { pubKeyBytes := []byte{0x00} switch algo { case chainec.ECTypeSecp256k1: pubKeyBytes[0] = byte(chainec.ECTypeSecp256k1) case chainec.ECTypeEdwards: pubKeyBytes[0] = byte(chainec.ECTypeEdwards) case chainec.ECTypeSecSchnorr: pubKeyBytes[0] = byte(chainec.ECTypeSecSchnorr) } // Pubkeys are encoded as [0] = type/ybit, [1:33] = serialized pubkey compressed := serializedPK if algo == chainec.ECTypeSecp256k1 || algo == chainec.ECTypeSecSchnorr { pub, err := chainec.Secp256k1.ParsePubKey(serializedPK) if err != nil { return "" } pubSerComp := pub.SerializeCompressed() // Set the y-bit if needed. if pubSerComp[0] == 0x03 { pubKeyBytes[0] |= (1 << 7) } compressed = pubSerComp[1:] } pubKeyBytes = append(pubKeyBytes, compressed...) return base58.CheckEncode(pubKeyBytes, netID) }
// This example demonstrates how to encode data using the Base58Check encoding // scheme. func ExampleCheckEncode() { // Encode example data with the Base58Check encoding scheme. data := []byte("Test data") var ver [2]byte ver[0] = 0 ver[1] = 0 encoded := base58.CheckEncode(data, ver) // Show the encoded data. fmt.Println("Encoded Data:", encoded) // Output: // Encoded Data: 1182iP79GRURMp6PPpRX }
func TestBase58Check(t *testing.T) { for x, test := range checkEncodingStringTests { var ver [2]byte ver[0] = test.version ver[1] = 0 // test encoding if res := base58.CheckEncode([]byte(test.in), ver); res != test.out { t.Errorf("CheckEncode test #%d failed: got %s, want: %s", x, res, test.out) } // test decoding res, version, err := base58.CheckDecode(test.out) if err != nil { t.Errorf("CheckDecode test #%d failed with err: %v", x, err) } else if version != ver { t.Errorf("CheckDecode test #%d failed: got version: %d want: %d", x, version, ver) } else if string(res) != test.in { t.Errorf("CheckDecode test #%d failed: got: %s want: %s", x, res, test.in) } } // test the two decoding failure cases // case 1: checksum error _, _, err := base58.CheckDecode("Axk2WA6M") if err != base58.ErrChecksum { t.Error("Checkdecode test failed, expected ErrChecksum") } // case 2: invalid formats (string lengths below 5 mean the version byte and/or the checksum // bytes are missing). testString := "" for len := 0; len < 4; len++ { // make a string of length `len` _, _, err = base58.CheckDecode(testString) if err != base58.ErrInvalidFormat { t.Error("Checkdecode test failed, expected ErrInvalidFormat") } } }
// encodeAddress returns a human-readable payment address given a ripemd160 hash // and netID which encodes the network and address type. It is used in both // pay-to-pubkey-hash (P2PKH) and pay-to-script-hash (P2SH) address encoding. func encodeAddress(hash160 []byte, netID [2]byte) string { // Format is 2 bytes for a network and address class (i.e. P2PKH vs // P2SH), 20 bytes for a RIPEMD160 hash, and 4 bytes of checksum. return base58.CheckEncode(hash160[:ripemd160.Size], netID) }