fix: encode public_key_type fields as 33-byte binary blobs#11
Merged
Conversation
Steem's public_key_type serializes as a fixed 33-byte blob (1 byte format + 32 bytes key data), not as a varint-prefixed string. The reflection encoder was treating BlockSigningKey/MemoKey as plain strings, producing 54 bytes instead of 33. Fix: - Add steem:"pubkey" struct tag for public_key_type string fields - Add encodePubKey() to encoder: parses STM... string via wif.PublicKey and writes the 33-byte compressed binary - Tag all MemoKey and BlockSigningKey fields in protocol/operations.go - Update golden hex in TestWitnessUpdateGoldenHex (131→110 bytes)
Add byte-exact golden hex serialization tests for every operation that contains a public_key_type field (memo_key, block_signing_key): - TestWitnessUpdateSerialization (block_signing_key) - TestAccountCreateSerialization (memo_key + plain authorities) - TestAccountUpdateSerialization (memo_key + optional nil authorities) - TestAccountUpdate2Serialization (memo_key + optional + extensions) - TestCreateClaimedAccountSerialization (memo_key + plain + extensions) - TestAccountCreateWithDelegationSerialization (memo_key + delegation) Each test hardcodes the expected hex and compares byte-for-byte. The golden hex values were generated from the fixed encoder and verified against Steem's C++ FC_REFLECT serialization format. Also fixes three operations where steem:"pubkey" tag was missing (CreateClaimedAccount, AccountCreateWithDelegation, AccountUpdate2).
kuny0707
approved these changes
Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
public_key_typefields (likeblock_signing_keyinwitness_update,memo_keyinaccount_create/account_update) were serialized asvarint-prefixed strings by the reflection encoder. In Steem's C++ binary
format,
public_key_typeis a fixed 33-byte blob (1 byte format + 32 byteskey data), not a variable-length string.
This caused a digest mismatch on every transaction involving public keys:
the SDK computed the digest using a 54-byte varint-string represe ntation,
while steemd expected a 33-byte binary format.
Fix
steem:"pubkey"struct tag forpublic_key_typestring fieldsencodePubKey()to the encoder: parsesSTM...→wif.PublicKeyand writes the 33-byte compressed binary
BlockSigningKeyinWitnessUpdateOperation, and allMemoKeyfields in
AccountCreate,AccountUpdate,CreateClaimedAccount,AccountUpdate2,AccountCreateWithDelegationoperationsTestWitnessUpdateGoldenHex(131 → 110 bytes)Verification
Tested with a live witness signing key update on Steem mainnet —
transaction
a840f7c70d3549ac53fcd83ca5740f2092364b03accepted atblock 107590219.