#Cross contract deployment error

49 messages · Page 1 of 1 (latest)

lime panther
#

Hello, I am trying to deploy a contract from another contract. The deploy function deploys the contract in a first call but if call the deploy function second time it gives this error:

#

Here is my code..

#

yes

#

yes

brittle topaz
#

This is a scam

lime panther
#

Spaming me haha..

#

Yeah got that

brittle topaz
#

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?

lime panther
#

Looks like the same issue

#

But couldn’t solve it

brittle topaz
#

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

lime panther
#

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.

brittle topaz
#

I would try to change the salt to a random value, unless you have a specific need to have it deterministic

lime panther
#

Will this work for n number of times?

#

Might need to deploy multiple number of contracts

brittle topaz
#

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

lime panther
#

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.

fleet jolt
#

Ya u need unique salts

abstract void
# fleet jolt 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.

fleet jolt
#

Thanks Leigh! And sorry to OP for not explaining my answer better 😛

foggy apex
#

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)

fleet jolt
# foggy apex > There's multiple ways to do this. You could use the env.prng() to generate a r...

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?

foggy apex
#

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

fleet jolt
#

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

foggy apex
#

(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)

fleet jolt
#

I'll make sure to put some consideration into this.

#

Might have some more questions in the future

foggy apex
#

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

fleet jolt
#

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

left apex
#

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?

lime panther
#

I don’t think you can deploy multiple contracts with same salt.

left apex
#

Can you show me an example of how you did that?

lime panther
#

I can share it in a while . May be 1-2 hours ?

left apex
#

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 🙂

lime panther
#

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.

left apex
#

Hmm not sure if that would actually work if more then 1 person uses it. Because right now the first contract will have a salt of 32x0 and when I also deploy to testnet my first contract will have the same salt

#

But thanks for the example this helps me get further 🙂