본문으로 건너뛰기

Updating Contracts

NEAR 계정은 로직(컨트랙트의 코드)을 상태(스토리지)와 분리하여, 코드를 변경할 수 있습니다.

컨트랙트는 두 가지 방법으로 업데이트할 수 있습니다.

  1. Through tools such as NEAR CLI or near-api-js (if you hold the account's full access key).
  2. Programmatically, by implementing a method that takes the new code and deploys it.

Updating Through Tools

NEAR CLI 등 선호하는 도구를 사용하여 다른 컨트랙트를 재배포하기만 하면 됩니다.

# (optional) If you don't have an account, create one
near create-account <account-id> --useFaucet

# Deploy the contract
near deploy <account-id> <wasm-file>

프로그래밍을 통한 업데이트

스마트 컨트랙트를 다음과 같은 방법을 구현하여 자체적으로 업데이트할 수도 있습니다.

  1. Takes the new wasm contract as input
  2. Promise를 생성하여 자체적으로 배포합니다.
self-updates/base/src/update.rs
loading...

How to Invoke Such Method?

# Load the contract's raw bytes
CONTRACT_BYTES=`cat ./path/to/wasm.wasm | base64`

# Call the update_contract method
near call <contract-account> update_contract "$CONTRACT_BYTES" --base64 --accountId <manager-account> --gas 300000000000000
DAO Factories

This is how DAO factories update their contracts


Migrating the State

Since the account's logic (smart contract) is separated from the account's state (storage), the account's state persists when re-deploying a contract.

Because of this, adding methods or modifying existing ones will yield no problems.

However, deploying a contract that modifies or removes structures stored in the state will raise an error: Cannot deserialize the contract state, in which case you can choose to:

  1. 다른 계정 사용
  2. Rollback to the previous contract code
  3. 컨트랙트 상태를 마이그레이션하는 메서드 추가

마이그레이션 메서드

상태를 마이그레이션하는 것 외에 다른 옵션이 없는 경우 다음과 같은 메서드를 구현해야 합니다.

  1. Reads the current state of the contract
  2. 새로운 상태로 변환하기 위해 다른 함수를 적용합니다.
  3. 새로운 상태를 반환합니다.
DAO Update

이것이 DAO가 스스로를 업데이트하는 방법입니다.


예제: 방명록 마이그레이션

메시지를 저장하는 방명록이 있고, 사용자가 이러한 메시지에 대해 "프리미엄"으로 지불할 수 있다고 상상해 보세요. 다음과 같은 상태를 사용하여 메시지 및 결제를 추적할 수 있습니다.

basic-updates/base/src/lib.rs
loading...

컨트랙트 업데이트

만약 어느 시점에서 PostedMessagepayments를 추적할 수 있다는 것을 깨달아서, 컨트랙트를 다음과 같이 변경했다고 해봅시다.

basic-updates/update/src/lib.rs
loading...

호환되지 않는 상태

초기화된 계정에 업데이트를 배포하면, 다음과 같은 이유로 컨트랙트는 계정 ​​상태를 역직렬화하지 못합니다.

  1. (이전 컨트랙트로부터) 상태에 저장된 추가 payments 벡터가 존재합니다.
  2. 저장된 PostedMessages에는 (이전 컨트랙트와 같이) payment 필드가 존재하지 않습니다.

Migrating the State

이 문제를 해결하려면, 이전 상태를 거쳐 payments 벡터를 제거하고, PostedMessages에 정보를 추가하는 메서드를 구현해야 합니다.

basic-updates/update/src/migrate.rs
loading...

실제로 migrate는 기존 상태([#init(ignore_state)])를 무시하는

You can follow a migration step by step in the official migration example

Was this page helpful?