ton-blockchain / ton

Main TON monorepo
Other
2.99k stars 919 forks source link

Problem with calculating storage contract address #787

Open liminalAngel opened 12 months ago

liminalAngel commented 12 months ago

The following function:

slice get_storage_contract_address(int merkle_hash, int file_size, slice client, int torrent_hash) method_id {
    var (_, rate_per_mb_day, max_span, _, _) = get_storage_params();
    cell state_init = build_storage_contract_stateinit(merkle_hash, file_size, rate_per_mb_day, max_span, client, torrent_hash);
    return calculate_address_by_stateinit(state_init);
} 

returns different addresses every time you call it. It occurs because of this line in build_storage_contract_stateinit function:

.store_uint(now(), 32) ;; last_proof_time

I propose you to use another function calculate_storage_contract_stateinit which will take an argument last_proof_time:

cell calculate_storage_contract_stateinit(int merkle_hash, int file_size, int rate_per_mb_day,
        int max_span, int last_proof_time, slice client, int torrent_hash) {
    cell data = begin_cell()
            .store_int(0, 1) ;; active
            .store_coins(0) ;; client balance
            .store_slice(my_address())
            .store_uint(merkle_hash, 256)
            .store_uint(file_size, 64)
            .store_uint(0, 64) ;; next_proof
            .store_coins(rate_per_mb_day)
            .store_uint(max_span, 32)
            .store_uint(last_proof_time, 32) ;; last_proof_time
            .store_ref(begin_cell()
                    .store_slice(client)
                    .store_uint(torrent_hash, 256)
                    .end_cell())
            .end_cell();

    cell state_init = begin_cell()
            .store_uint(0, 2)
            .store_maybe_ref(storage_contract_code())
            .store_maybe_ref(data)
            .store_uint(0, 1) .end_cell();
    return state_init;
}

This way we will be able to calculate storage contract's address correctly:

slice get_storage_contract_address(int merkle_hash, int file_size, int last_proof_time, slice client, int torrent_hash) method_id {
    var (_, rate_per_mb_day, max_span, _, _) = get_storage_params();
    cell state_init = calculate_storage_contract_stateinit(merkle_hash, file_size, rate_per_mb_day, max_span, last_proof_time, client, torrent_hash);
    return calculate_address_by_stateinit(state_init);
}
EmelyanenkoK commented 11 months ago

Probably we need to use last_proof_time==0 for init state and then set correct time upon storage contract initialisation.

liminalAngel commented 11 months ago

This way we also won't be able to calculate correct address