The past few weeks have shown that testing new or changed blockchain functionality - before it is deployed to the production systems - is a crucial process also for Steem. Steem testnets are available from multiple sources, including the Steemit official testnet at https://testnet.steemitdev.com .
However, testnets are not an exact 1:1 copy of the production chain. They often have a custom prefix and own asset symbols. The prefix is, among others, used as the first characters in the string representation of public keys.
|Steem prod-chain||Steemit testnet|
Other use cases are the recently added initial support for the EFTG chain, Whaleshares.io, Weku, VIT, or others, where asset names are also different from the default Steem assets. While this seems like a trivial detail, providing the correct values to the transaction signing logic is crucial to properly sign transactions that are accepted by the corresponding chain.
Adding chain prefix handling
Let's take a transfer operation as an example, attempting to transfer "0.001 TESTS" to myself on the testnet:
from beem import Steem from beem.account import Account import getpass key = getpass.getpass("active key: ") s = Steem(node=['https://testnet.steemitdev.com'], keys=[key]) s.chain_params["chain_id"] = "46d82ab7d8db682eb1959aed0ada039a6d49afa1602491f93dde9cac3e8e6c32" a = Account('crokkon', steem_instance=s) print(a.transfer('crokkon', 0.001, 'TESTS'))
(Note: the chain_id override is required because the Steemit testnet reports a different chain_id than what it is using internally)
This snipped previously failed with an
Exception: Asset unknown error. What happened in the background was that the amount "0.001 TESTS" was internally transformed into an
Amount() instance. This step handled the asset "TESTS" correctly because it knows about the chain assets from the
Steem() instance passed as one argument. The serialization step, however, failed because this chain/asset information was not passed on from there and the code didn't find the correct asset symbol in the default Steem chain parameters.
The situation was addressed by forwarding the chain prefix information into all chain-dependent object serialization methods: By providing the corresponding chain prefix to the transaction serialization logic, beem can now be used with any asset symbols and therefore any testnet or third-party Steem blockchain with non-default asset names. The above code sample works without an error now.
Adding generic symbol names
The forwarding of the chain prefix in the serialization/transaction signing step makes it possible to use any blockchain ops also on the testnet or other third-party chains from the low-level
TransactionBuilder interface or selected higher-level functions like
Account.transfer() shown above. However, at various places across the code were references to amounts in STEEM, SBD or VESTS with hard-coded symbol names, especially in default values:
def claim_account(self, creator, fee="0 STEEM", **kwargs): [...] default_max_payout = "1000000.000 SBD"
Assignments like these are perfectly fine for the operation with the production chain, but bring asset name problems with the testnet or other third-party chains. For that reason, generic asset symbols were introduced: By adding asset symbol name properties for the equivalent of SBD, STEEM and VESTS of the currently used chain, these cases can be handled dynamically. e.g.
steem.sbd_symbol will return 'SBD' on the production chain, but 'TBD' when connected to the Steemit testnet. With these properties, any default amounts in the code can use the corresponding asset symbols of the current chain without using hard-coded values.