Protocol 28: SDK Changes
XDR Changes
The XDR specification requires upgrading to stellar-xdr@9c9c145 (Protocol 28 XDR). Both new CAPs are ungated at that commit, so no preprocessing feature flags are needed. Two CAPs add new types:
CAP-83 is consensus-internal; regenerating from the new XDR is the only change SDKs need. CAP-85 requires the handling below.
CAP-85: External Contract Executables
A contract instance can now hold a CONTRACT_EXECUTABLE_EXTERNAL_REF executable (an executable_owner address plus a tag) instead of its own Wasm hash. Things to keep in mind when updating:
- Resolving a reference: any path that maps an instance to its code (Wasm fetchers, spec loaders, contract-client constructors, binding generators) must handle the new arm. The Wasm hash lives in the owner's persistent contract data entry keyed by
SCV_EXECUTABLE_TAG(tag); read it with one extra getLedgerEntries call, then proceed as for CONTRACT_EXECUTABLE_WASM.
- Tag handling: a tag is an unbounded
SCString and may not be valid UTF-8, and it identifies the code being deployed, so never decode it leniently. Show it as a string only when valid UTF-8 (raw bytes otherwise), and build the ledger key from the original bytes.
- Rendering invocation trees:
CREATE_CONTRACT / CREATE_CONTRACT_V2 invocations can now carry an external-ref executable, so auth-display code must render the new creation type (owner, tag, constructor args for V2) instead of failing. Contract ID derives from deployer plus salt, same as Wasm.
- Building deploy operations: deploy helpers should accept an external reference (owner address plus tag) as an alternative to a Wasm hash. Reject a non-contract owner early and pass binary tags through undecoded.
CAP-71 Default Flip
Unrelated to Protocol 28 itself: js-stellar-sdk v17 has flipped its CAP-71 defaults to SOROBAN_CREDENTIALS_ADDRESS_V2, on both ends of the auth flow (authorizeInvocation builds V2 entries and simulateTransaction sends useUpgradedAuth: true, each with a legacy opt-out). See the Protocol 27 announcement for the auth changes themselves.
Reference Implementations
- js-stellar-sdk (v17.0.0): CAP-85 resolution and rendering in #1577 (
rpc.Server.getExternalRefWasmHash, contract.Client.from, buildInvocationTree, scValToNative, binding generation), deploying from an external ref via Operation.createCustomContract in #1665, and the CAP-71 default flip in #1562.
- go-stellar-sdk (v0.7.0+): regenerated Protocol 28 XDR.
- stellar-rpc (v28.0.0): Protocol 28 XDR and preflight hosts (#913);
useUpgradedAuth handling in internal/methods/simulate_transaction.go.
- stellar-horizon (v28.0.0, in release): CAP-85 ingestion support (#207, #213).
Protocol 28: SDK Changes
XDR Changes
The XDR specification requires upgrading to stellar-xdr@
9c9c145(Protocol 28 XDR). Both new CAPs are ungated at that commit, so no preprocessing feature flags are needed. Two CAPs add new types:CAP-83 is consensus-internal; regenerating from the new XDR is the only change SDKs need. CAP-85 requires the handling below.
CAP-85: External Contract Executables
A contract instance can now hold a
CONTRACT_EXECUTABLE_EXTERNAL_REFexecutable (anexecutable_owneraddress plus atag) instead of its own Wasm hash. Things to keep in mind when updating:SCV_EXECUTABLE_TAG(tag); read it with one extragetLedgerEntriescall, then proceed as forCONTRACT_EXECUTABLE_WASM.SCStringand may not be valid UTF-8, and it identifies the code being deployed, so never decode it leniently. Show it as a string only when valid UTF-8 (raw bytes otherwise), and build the ledger key from the original bytes.CREATE_CONTRACT/CREATE_CONTRACT_V2invocations can now carry an external-ref executable, so auth-display code must render the new creation type (owner, tag, constructor args for V2) instead of failing. Contract ID derives from deployer plus salt, same as Wasm.CAP-71 Default Flip
Unrelated to Protocol 28 itself: js-stellar-sdk v17 has flipped its CAP-71 defaults to
SOROBAN_CREDENTIALS_ADDRESS_V2, on both ends of the auth flow (authorizeInvocationbuilds V2 entries andsimulateTransactionsendsuseUpgradedAuth: true, each with a legacy opt-out). See the Protocol 27 announcement for the auth changes themselves.Reference Implementations
rpc.Server.getExternalRefWasmHash,contract.Client.from,buildInvocationTree,scValToNative, binding generation), deploying from an external ref viaOperation.createCustomContractin #1665, and the CAP-71 default flip in #1562.useUpgradedAuthhandling ininternal/methods/simulate_transaction.go.