#Cross contract deployment error
49 messages · Page 1 of 1 (latest)
This is a scam
I don't know for sure the answer for your problem though
But it might be that it's trying to deploy again with the same salt, resulting in the same address?
As you have a salt that is 32x 0, and if the wasm is the same, I feel it might result in the same deployed_address
Can we deploy it using with_stellar_asset instead of with_address ?
This functions does not need salt. But it needs serialized_asset , and no idea how to generate it.
I would try to change the salt to a random value, unless you have a specific need to have it deterministic
Will this work for n number of times?
Might need to deploy multiple number of contracts
Multiple of the same contracts? As in, with the same WASM? Then I think you need a unique salt for each. So far I could find only examples which take the salt as an argument from the invocation
Yeah the same new contract needs to be deployed every time the deploy function is called .
The problem is, the deploy function successfully deploys at the first call but gives error for the second call.
The idea is whoever user calls this function they own their own contract.
Ya u need unique salts
To expand on this, the contract address of the contract being deployed is derived from the deployer (the contract doing the deployment) and the salt.
In the code the salt is a hardcoded fixed value, so the contract address is the same everytime, and you can only deploy to a contract ID once.
So you need to use a different salt for each deployment.
There's multiple ways to do this. You could use the env.prng() to generate a random ID. Or you can store a counter and increment it on each deployment and use that as the salt. Or you can make the salt an input and let the person invoking the deployer choose the salt so that they can predict what the deployed contract ID will be.
Thanks Leigh! And sorry to OP for not explaining my answer better 😛
There's multiple ways to do this. You could use the env.prng() to generate a random ID.
this won't work, because created contract id has to be in the footprint
Or you can store a counter and increment it on each deployment and use that as the salt.
that won't work well either in case if there is several creation requests in a short period of time that want to create the same entry (one will succeed ,the remaining ones will fail)
Or you can make the salt an input and let the person invoking the deployer choose the salt so that they can predict what the deployed contract ID will be.
I think this is the only recommended way to approach this; created contract ID should ideally be a function of the creation request inputs. mixing in any ledger state will lead to trouble. now, you can do random salt generation off-chain, or derive the id from some unique input parameters (e.g. for liquidity pool salt probably should be the hash of the asset pair)
Well You just got me thinking that something I thought i had already figured out and resolved, may in fact have a flaw in my logic...
very simplified way of how it works, but on the contracts i'm writing i needed to be able to derive a list of all the contract addresses that have been installed, so I keep a counter of the number of times the deployer has deployed and basically i use that as the salt, then I can know it's been deployed 30 times, so i don't need to keep 30 addresses in storage and pay the storage fees associated with that...
However I didn't think about your second point of that more than one deployment in a ledger will cause this system to break. do you have any suggestion on how i can get around that?
if on-chain auto-increment is a hard requirement then there isn't really way around it. it just makes your protocol 'sequential' (as in, you'd probably want to only deploy a single contract every few ledgers). if that's fine, then you can have your autoincrement. however, if your factory is expected to be used in a decentralized fashion, then key collisions might annoy your users
so I'd say the default recommendation should be off-chain salt, but if you benefit from autoincrement in some other way besides salt generation, then it's not a huge deal to use it
Yeah in this case i don't see that being an issue tbh since it's used by the "communidao" contract which deploys "communi-cores" and communi-cores deploy voting contracts, but none of these things are likely to happen in high volume like that... but i still think it'd probably be better to avoid it if possible
Ideally the salt would be generated by my contract in a predicable way because if it's done offchain by the dapp, then someone calls the contract without the dapp perhaps it would get out of order
(it's also more about spikes - like if you need to deploy two contracts at the same time, you're risking that one of them fails)
I'll make sure to put some consideration into this.
Might have some more questions in the future
sure. FWIW this is more of a general thing about autoincrements. in classic the autoincrement (account sequnce number) is accounted for at the protocol and mempool levels (so we would make sure we don't try to apply transactions out of order and won't charge any fees). since soroban autoincrements are unknown to the protocol, they can and will fail at the runtime due to either key conflicts or out-of-order execution (because, again, we don't enforce any particular execution order for soroban transactions). that's why e.g. nonces are temporary entries and not a single autoincrement
Thanks for the perspective, even knowing this, it's still useful that it was brought to my attention, because even though it's obvious it wasn't something i was thinking of until now lol
I am running into the same problem but my contract is deploying 3 contracts. I did get it to work when supplying 3 salts to the function but I really don't like having to input 3 salts. Is there any way I could use a single salt as input to deploy 3 contracts?
You can store a salt counter and increment it after deploying. I solved it that way.
I don’t think you can deploy multiple contracts with same salt.
Can you show me an example of how you did that?
I can share it in a while . May be 1-2 hours ?
Because then I can use 1 salt and increament it for each contract I am fine with supplying a single salt each deploy call but multiple does not sound right
That would be amazing thank you 🙂
This is something i have done. You can also give the salt as parameter and increment it every time , this way you need not store it in db.
Also, once you have deployed a contract using a salt value say 1, you cannot deploy the same contract using same salt 1. This will give you an error. This should be kept in mind. This is because there already exist the contract address with that salt in the testnet so cannot deploy duplicate contract in that testnet.