- Overview
- Tutorials
- Getting started
- Get started with Canton and the JSON Ledger API
- Get Started with Canton, the JSON Ledger API, and TypeScript
- Get started with Canton Network App Dev Quickstart
- Get started with smart contract development
- Basic contracts
- Test templates using Daml scripts
- Build the Daml Archive (.dar) file
- Data types
- Transform contracts using choices
- Add constraints to a contract
- Parties and authority
- Compose choices
- Handle exceptions
- Work with dependencies
- Functional programming 101
- The Daml standard library
- Test Daml contracts
- Next steps
- Application development
- Getting started
- Development how-tos
- Component how-tos
- Explanations
- References
- Application development
- Smart contract development
- Daml language cheat sheet
- Daml language reference
- Daml standard library
- DA.Action.State.Class
- DA.Action.State
- DA.Action
- DA.Assert
- DA.Bifunctor
- DA.Crypto.Text
- DA.Date
- DA.Either
- DA.Exception
- DA.Fail
- DA.Foldable
- DA.Functor
- DA.Internal.Interface.AnyView.Types
- DA.Internal.Interface.AnyView
- DA.List.BuiltinOrder
- DA.List.Total
- DA.List
- DA.Logic
- DA.Map
- DA.Math
- DA.Monoid
- DA.NonEmpty.Types
- DA.NonEmpty
- DA.Numeric
- DA.Optional
- DA.Record
- DA.Semigroup
- DA.Set
- DA.Stack
- DA.Text
- DA.TextMap
- DA.Time
- DA.Traversable
- DA.Tuple
- DA.Validation
- GHC.Show.Text
- GHC.Tuple.Check
- Prelude
- Smart contract upgrading reference
- Glossary of concepts
Submit Externally Signed Transactions - Part 2¶
Complete Part 1 before proceeding.
The tutorial illustrates the external signing process using two external parties, Alice
and Bob
,
leveraging the same Ping Daml Template used in Part 1 of the tutorial.
In Part 1
Alice
created aPing
contract.In Part 2
Bob
exercises theRespond
choice on the contract and archives it.
The majority of the work involved in external transaction signing was completed in Part 1. The key addition in Part 2 is utilizing the Ping contract created earlier through explicit disclosure and executing the Respond choice on that contract. The overall process remains similar to Part 1.
Important
This tutorial is for demo purposes. The code snippets should not be used directly in a production environment.
Setup¶
To proceed, gather the following information:
Bob
’s Party ID, protocol signing private key, and protocol signing public key fingerprintSynchronizer ID of the synchronizer to which the participant is connected
gRPC Ledger API endpoint
ping_created_event
: Event retrieved in the last step of Part 1.contract_id
: ID of the contract created in Part 1.
This information should already be known from the onboarding tutorial and the first part of the external signing tutorial.
Python¶
If you are following this tutorial in Python, generate gRPC Python classes by following the setup instructions in the README
in the example folder.
Exercise Respond
Choice¶
This tutorial does not repeat the material covered in Part 1 regarding transaction preparation, validation, signing, and execution, as these steps remain largely the same. Instead, it highlights the key differences from Part 1.
Prepare the transaction¶
Create the exercise command¶
ping_exercise_command = commands_pb2.Command(
exercise=commands_pb2.ExerciseCommand(
template_id=ping_template_id,
contract_id=contract_id,
choice="Respond",
choice_argument=value_pb2.Value(
record=value_pb2.Record(record_id=None, fields=[])
),
)
)
Prepare the exercise command¶
prepare_exercise_request = interactive_submission_service_pb2.PrepareSubmissionRequest(
user_id=user_id,
command_id=str(uuid.uuid4()),
act_as=[responder],
read_as=[responder],
synchronizer_id=synchronizer_id,
commands=[ping_exercise_command],
# We need to explicitly disclosed the ping contract we created earlier
disclosed_contracts=[
commands_pb2.DisclosedContract(
template_id=template_id,
contract_id=contract_id,
created_event_blob=created_event_blob,
synchronizer_id=synchronizer_id,
)
],
)
prepare_exercise_response = iss_client.PrepareSubmission(prepare_exercise_request)
The Prepare
request is very similar to the one from Part 1, with the following differences:
act_as
: Now theresponder
,Bob
, instead of theinitiator
,Alice
. This makes sense becauseBob
is the one exercising the choice on the contract.commands
: The command is now anExercise``command instead of a ``Create
command. Notably it requires thecontract_id
from Part 1.disclosed_contracts
: The serialized representation of contracts required to process the transaction.
Metadata¶
The only significant difference with Part 1 in the metadata is: disclosed_events
.
This field now contains the input Ping
contract. It is also included in the hash of the transaction.
Important
Like in Part 1, the transaction must be validated, hashed and signed.
The hash computation and signature is performed by the execute_and_get_contract_id
function provided at the end of Part 1, as shown in the next section.
Submit and observe archived contract¶
Submit the exercise transaction and observe the contract being archived¶
execute_and_get_contract_id(
prepared_exercise_transaction,
responder,
responder_private_key,
responder_fingerprint,
)
# The contract was archived by exercising the choice, we get an archived event this time
contract_events = get_events(responder, contract_id)
if contract_events.HasField("archived"):
print(
f"Ping contract with ID {contract_events.archived.archived_event.contract_id} has been archived"
)
else:
raise Exception("Expected an archive event")
By querying the event service and filtering for the contract ID, an archived event is observed, confirming that the contract has been successfully archived.
This concludes the external signing tutorial.
The code used in this tutorial is available in the examples/08-interactive-submission
folder and can be run with
python interactive_submission.py run-demo
Tooling¶
The scripts mentioned in this tutorial can be used as tools for testing and development purposes
Decode base64 encoded prepared transaction to JSON¶
./setup.sh
python daml_transaction_util.py --decode --base64 <base64_encoded_transaction>
Compute hash of base64 encoded prepared transaction¶
./setup.sh
python daml_transaction_util.py --hash --base64 <base64_encoded_transaction>