Instead of duplicating the code for the two contracts like in the previous example, we can write the code once and still deploy two separate instances. Each instance will have its own unique address.
We can do this by adding an argument to init()
. When deploying the contract, we need to specify its init arguments. In this example we deploy twice, the first with the argument 1 and the second is deployed with 2.
We mentioned earlier that contract addresses on TON are derived from the initial code of the contract (the compiled bytecode) and the initial data of the contract (the arguments of init).
Since we wrote the code once, the initial code is now identical. By adding an contructor argument, we've made the initial data different. This is why we're going to get two different addresses.
All Examplesimport "@stdlib/deploy"; // we have multiple instances of the children contract TodoChild { 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); } } // we have one instance of the parent contract TodoParent with Deployable { numChildren: Int as uint64; init() { self.numChildren = 0; } // this message handler will cause the contract to deploy another child receive("deploy another") { self.numChildren = self.numChildren + 1; let init: StateInit = initOf TodoChild(self.numChildren); send(SendParameters{ to: contractAddress(init), 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 }); } get fun numChildren(): Int { return self.numChildren; } }