In a parent-child relationship, the user would normally just deploy the parent. This is what's happening here when you press the Deploy button.
In this example, the user is only supposed to communicate with the parent. You can send the parent contract a message by pressing the Send greet 3 button.
This message will instruct the parent to send its own HiFromParent
message to the first 3 children. Every child will respond to the greeting by sending the parent its own HiFromChild
back.
You can't send a message to a contract until it is deployed. How can the parent guarantee that they're not communicating with a child that wasn't deployed yet?
The best practice is to include the stateInit on every message. This way, if the child isn't deployed, it will be. If the child is already deployed, this field will be ignored.
This is called lazy deployment.
All Examplesimport "@stdlib/deploy"; // we're going to have multiple instances of this contract, each with a different seqno contract Todo with Deployable { seqno: Int as uint64; // when deploying an instance, we must specify its index (sequence number) init(seqno: Int) { self.seqno = seqno; } // this message handler will just debug print the seqno so we can see when it's called receive("identify") { dump(self.seqno); } // this message handler will cause the contract to deploy the second instance receive("deploy 2nd") { let init: StateInit = initOf Todo(2); let address: Address = contractAddress(init); send(SendParameters{ to: address, value: ton("0.1"), // pay for message, the deployment and give some TON for storage mode: SendIgnoreErrors, code: init.code, // attaching the state init will cause the message to deploy data: init.data, body: "identify".asComment() // we must piggyback the deployment on another message }); } }