Workshop Prerequisites
Please complete the instructions found here in order to be prepared for the hands on portion of the workshop. If you have questions about these prerequisites, we'll do our best to provide assistance on RocketChat in the #indy channel.
Useful Links and Additional Reading
...
- To get started we will create a test that writes a nym with an image, then retrieves it from the ledger, and finally checks the returned image is correct.
Inindy_node/test/nym_txn/test_nym_additional.py
around line 90 add this test.Code Block language py title test_nym_img def test_nym_img(looper, sdk_pool_handle, sdk_wallet_steward, endorser_did_verkey): # prepare txn did, verkey = endorser_did_verkey nym_request, _ = looper.loop.run_until_complete( prepare_nym_request(sdk_wallet_steward, None, None, ENDORSER_STRING, did, verkey, False if verkey else True)) # modify transaction to include image hyperledger_logo = 'https://raw.githubusercontent.com/hyperledger/indy-node/master/collateral/logos/indy-logo.png' txn = json.loads(nym_request) txn['operation']['img'] = hyperledger_logo # don't do this, avoid private data on ledgers request_couple = sdk_sign_and_send_prepared_request(looper, sdk_wallet_steward, sdk_pool_handle, json.dumps(txn)) sdk_get_and_check_replies(looper, [request_couple]) # check image is in the nym rep = get_nym(looper, sdk_pool_handle, sdk_wallet_steward, did) assert rep[0][1]['result']['data'] assert json.loads(rep[0][1]['result']['data'])['img'] == hyperledger_logo
- Inside
indy_node/test/nym_txn
directory,pytest -k test_nym_img
should result in a failing test.
- Now that we have a failing test we can start updating nym write transaction types. In
indy_common/types.py
there is a class calledClientOperationField
around line 470. This class extends operations. Looks like Indy Node does not change the basic nym operations, we will borrow some code from Indy Plenum that defines a new operation. We will define in the next steps a new ClientNYMOperation. Since we are here let's add the instantiation inside _specific_operations.Code Block language py title nym operation ... class ClientOperationField(PClientOperationField): _specific_operations = { NYM: ClientNYMOperation(), # <----- new operation SCHEMA: ClientSchemaOperation(), ATTRIB: ClientAttribOperation(), ...
Around line 72 we will copy in the
ClientNYMOperation
class from Indy Plenum with our extraimg
field.Code Block language py title nym operation class ClientNYMOperation(MessageValidator): schema = ( (TXN_TYPE, ConstantField(NYM)), (ALIAS, LimitedLengthStringField(max_length=ALIAS_FIELD_LIMIT, optional=True)), (VERKEY, VerkeyField(optional=True, nullable=True)), (TARGET_NYM, DestNymField()), (ROLE, RoleField(optional=True)), (IMG, LimitedLengthStringField(max_length=RAW_FIELD_LIMIT, optional=True)) # <----- new image field )
We also need to update some imports. Some of which we will define in the next steps.
Code Block language py title nym operation ... # include ALIAS, VERKEY from plenum.common.constants from plenum.common.constants import TARGET_NYM, NONCE, RAW, ENC, HASH, NAME, \ VERSION, FORCE, ORIGIN, OPERATION_SCHEMA_IS_STRICT, OP_VER, ALIAS, VERKEY ... # include VerkeyField, DestNymField from plenum.common.messages.fields from plenum.common.messages.fields import ConstantField, IdentifierField, \ ... AnyMapField, NonEmptyStringField, DatetimeStringField, RoleField, AnyField, FieldBase, VerkeyField, DestNymField ... from plenum.config import JSON_FIELD_LIMIT, NAME_FIELD_LIMIT, DATA_FIELD_LIMIT, \ NONCE_FIELD_LIMIT, \ ENC_FIELD_LIMIT, RAW_FIELD_LIMIT, SIGNATURE_TYPE_FIELD_LIMIT, ALIAS_FIELD_LIMIT ... # include NYM, IMG from indy_common.constants from indy_common.constants import TXN_TYPE, ATTRIB, GET_ATTR, \ ... RICH_SCHEMA_PRES_DEF, RS_PRES_DEF_TYPE_VALUE, NYM, IMG
- Now that we have a test, updated operator field we need to define the '
NYM
' string constant. Insideindy_common/constants.py
define a newNYM
constant around line 14.Code Block language py title nym constant # NYM IMG = "img"
- With the client operation for nym updated we will have transactions with our new "img" field. We now can update the nym handler.
inside
indy_node/server/request_handlers/domain_req_handlers/nym_handler.py
we will add a check for theimg
field, if present, store it. On line 78, add the check inside ofupdate_state
with supportingNYM
import.Code Block language py title nym handler ... from indy_common.constants import IMG, NYM <--- include NYM ... def update_state(self, txn, prev_result, request, is_committed=False): ... if IMG in txn_data: # check for IMG field new_data[IMG] = txn_data[IMG] # store IMG ...
- Inside
indy_node/test/nym_txn
directory,pytest -k test_nym_img
should result in a passing test. - Celebrate!
- You can find this coding example here, with a diff highlighting changes.