Can you deploy a new copy of a contract with SmartPy and simultaneously copy the storage of an already existing contract that has an identical model into the freshly deployed contract?
1 Answer
Yes, it is possible if you originate a contract from within a contract:
The example below duplicates the storage of Creator
when originating Created
. (This will not work if the storage contains tickets, only duplicable types are allowed)
import smartpy as sp
class Created(sp.Contract):
def __init__(self):
self.init(sp.big_map())
@sp.entry_point
def update(self):
self.data[1] -= 1
class Creator(sp.Contract):
def __init__(self):
self.init(sp.big_map({1: 2}))
@sp.entry_point
def create(self):
sp.create_contract(Created(), storage = self.data, amount = sp.amount)
@sp.entry_point
def update(self):
self.data[1] += 1
sp.add_compilation_target("Creator", Creator())
Doing this off-chain is more complicated. You will need to query the contract storage with /chains/main/blocks/head/context/contracts/<some_contract>/storage
, and if it contains any big_map, you will need to replace the { "int": <big_map_id> }
with the expanded map value by querying every big_map entry with /chains/main/blocks/head/context/big_maps/<big_map_id>
. (Gas and storage will be a limitation if the big_map has many entries)
-
when you say doing it "off-chain" do you mean it is possible from a fresh origination and you just have to prepare the data beforehand, or do you mean that that it is only possible if the contract to be migrated deploys the new contract and there are just extra steps if there are bigmaps?– 0x10Jul 7, 2022 at 5:21
-
1
-
1perfect, i was able to get this working but note the last part has
head/context/context/big_maps
in the url and it should just behead/context/big_maps
– 0x10Jul 7, 2022 at 8:34 -
1Yes, those hard limits are defined for operations and blocks and can be accessed at:
/chains/main/blocks/head/context/constants
. fieldmax_operation_data_length
Jul 7, 2022 at 9:40 -
1About the previous question. You can not have a big_map pointer
{ "int": <big_map_id> }
in the contract initial storage. You have to fetch all the entries and include it as map literal{ Elt ...; }
Jul 7, 2022 at 9:43