Klaytn 계정 마이그레이션

개별 EN을 사용하던 BApp을 KAS로 마이그레이션할 경우 참고하기 위한 문서입니다. EN을 사용하는 경우와 KAS를 사용하는 경우의 차이점 위주로 설명합니다.

EN에서 KAS로의 마이그레이션 순서

  1. KAS 가입, 인증 키 생성 : KAS를 사용하기 위해서는 사용자 가입 및 API 인증 키 생성이 필요합니다. 자세한 내용은 콘솔에서 시작하기 를 참고하세요.

    주의) 이렇게 생성한 인증 키를 Front End 코드에 바로 넣어서 사용하는 것은 보안상 매우 위험합니다. 접근이 제한된 Backend 서버에서 사용하십시오.

  2. 기존 코드에 인증키 추가 : KAS의 모든 API는 HTTP를 통해 요청할 수 있습니다. 이 때 각 호출은 헤더에 인증 정보를 포함하여야 합니다. Caver.js를 사용한다면 다음과 같은 형태로 호출할 수 있습니다.
    const accessKeyId = "{{your_accessKeyId}}";
    const secretAccessKey = "{{your_secretAccessKey}}";
    
    const option = {
       headers: [
         {name: 'Authorization', value: 'Basic ' +  Buffer.from(accessKeyId + ':' + secretAccessKey).toString('base64')},
         {name: 'x-chain-id', value: '8217'},
       ]
    }
    const caver = new Caver(new Caver.providers.HttpProvider("https://node-api.klaytnapi.com/v1/klaytn", option))
  3. 기존에 사용하던 키 이전 : 별도의 사용자별 Wallet이 아닌 EN을 키스토어로 사용한 경우라면, 기존에 사용하던 키의 마이그레이션이 필요할 수 있습니다. KAS에서 기존 키를 사용하기 위해서는 별도의 Wallet API를 사용하여야 하며 Wallet API에는 기존 키의 마이그레이션을 위한 API가 존재합니다. support@klaytnapi.com 으로 연락 주세요.
  4. 추가적인 코드 수정 : KAS는 일반 EN이 제공하는 JSON RPC API 중 제공되지 않는 것들이 있습니다. 혹시라도 이런 API를 사용하고 계신다면 해당하는 API를 다른 방식으로 수정해야 할 필요가 있을 수 있습니다. JSON RPC의 지원 여부를 확인하고자 하시는 경우 JSON-RPC API 를 참고하세요.

그 외 진행 중 문제가 있거나 궁금한 점이 있는 경우는 KAS 포럼, 또는 support@klaytnapi.com 으로 문의 주시기 바랍니다.

KAS SDK를 이용해 마이그레이션

기존 사용하던 Klaytn 계정을 KAS로 마이그레이션하기 위한 방법은 KAS SDK를 사용하는 방법과 직접 마이그레이션 코드를 작성하는 방법이 있습니다.

KAS SDK를 사용하는 방법은 아래와 같습니다.

JavaScriptJava
Copy
Copied
const keyring = caver.keyringContainer.keyring.generate();
const address = keyring.address;
const key = keyring.key.privateKey;
const nonce = 0;

const ret = await caver.kas.wallet.migrateAccounts([{ address, key, nonce }]);

// 아래와 같이 nonce를 직접 기입해주시지 않고도 사용하실 수 있습니다. nonce 값은 마이그레이션 과정에서 자동으로 채워집니다.
// const ret = await caver.kas.wallet.migrateAccounts([{ address, key }])
Copy
Copied
ArrayList<MigrationAccount> accountsToBeMigrated = new ArrayList<>();
SingleKeyring keyring = KeyringFactory.generate();
String address = keyring.getAddress();
String key = keyring.getKey().getPrivateKey();
String nonce = "0x0";

MigrationAccount migrationAccount = new MigrationAccount(address, key, nonce);
// 아래와 같이 nonce를 직접 기입해주시지 않고도 사용하실 수 있습니다. nonce 값은 마이그레이션 과정에서 자동으로 채워집니다.
// MigrationAccount migrationAccount = new MigrationAccount(address, key);

accountsToBeMigrated.add(migrationAccount);

RegistrationStatusResponse response = caver.kas.wallet.migrateAccounts(accountsToBeMigrated);

REST API를 이용해 마이그레이션

공개 키 생성

기존에 사용하던 Klaytn 계정을 KAS로 마이그레이션하기 위해서는 KAS에서 관리하는 공개 키를 이용해 업데이트해야 합니다. KAS에서 관리할 공개 키를 생성하기 위해서는 키 생성 API를 사용합니다. 공개 키는 한번에 최대 100개까지 생성할 수 있습니다. 아래와 같이 원하는 키의 갯수를 size 파라미터로 전달합니다.

API 호출

Copy
Copied
curl --location --request POST 'https://wallet-api.klaytnapi.com/v2/key' \
--header 'x-chain-id: 1001' \
-u {access-key-id}:{secret-access-key} \
--header 'Content-Type: application/json' \
--data-raw '{
    "size": 1
}'

API 응답

키 생성 API의 응답은 아래와 같습니다.

Copy
Copied
// 하나의 키 생성에 대한 응답 예시
{
  "items": [
    {
      "blob": "0x43bfd97caaeacc818cd6b62abccf21de569649f31f644142eb1fcfd5beb69e61",
      "keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
      "krn": "krn:1001:wallet:test:account-pool:default",
      "publicKey": "0x04a081eaf8603b9be528b86da338ba8051bfc073876dbdf00f5161b393b5735f85a76634ea38c43fbbc5d7a630b76ca2a1d81d446debc937b24a77eb3b352a1b6d"
    }
  ]
}

계정 업데이트 트랜잭션 생성

기존에 사용하던 계정의 개인 키로 계정 업데이트 트랜잭션을 생성해야 합니다.

danger

반드시 공개키 타입대납 계정 업데이트 트랜잭션으로 생성해야 합니다. 공개키 타입이 아닌 다른 계정 업데이트 트랜잭션을 만들면 계정을 사용하지 못할 수 있습니다.

Multisig 계정을 사용하고자 하는 경우에는 마이그레이션 절차를 모두 수행한 후에, Wallet API의 Multisig 계정 업데이트 API를 통해서 변경해 주시길 바랍니다.

API 호출

JavaScriptJava
Copy
Copied
// Klaytn 계정을 KAS Wallet API로 마이그레이션하기 위해서는 트랜잭션을 생성하고 이를 서명하여 KAS로 전송해야 합니다.
// 트랜잭션에 서명하기 위해 Klaytn 계정으로 Keyring 인스턴스를 생성하고 이를 KeyringContainer에 추가합니다.
// 만약 Klaytn 계정의 키가 `AccountKeyWeigthedMultiSig`이거나 `AccountKeyRoleBased`인 경우
// `keyringContainer.keyring.create` 의 두 번째 파라미터를 배열 혹은 이중 배열로 넘기면 됩니다.
// 더욱 자세한 내용은 https://ko.docs.klaytn.foundation/dapp/sdk/caver-js/api-references/caver.wallet/keyring#caver-wallet-keyring-create 를 참고해 주세요.
const keyringContainer = new caver.keyringContainer();
const keyring = keyringContainer.keyring.create(
  "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
  "0x{private key}"
);
keyringContainer.add(keyring);

// KAS Wallet API에 키를 생성합니다.
// `caver.kas.wallet.createKeys`를 통해 리턴되는 값의 형태는 아래와 같습니다.
// {
//     items: [
//         { blob: '0x06000...', keyId: 'krn:1001:...', krn: 'krn:1001:...', publicKey: '0x0400e...', },
//     ],
// }
const createdKeys = await caver.kas.wallet.createKeys(1);
const key = createdKeys.items[0];

// FeeDelegatedAccountUpdate 트랜잭션을 생성합니다.
// account 필드에 할당되는 값은 `caver.account.createWithAccountKeyPublic`를 사용하여 생성할 수 있으며
// 마이그레이션 하고자 하는 계정의 주소, 그리고 KAS Wallet API에 생성된 키(public key string 형태)를 파라미터로 전달해야 합니다.
const updateTx = new caver.transaction.feeDelegatedAccountUpdate({
  from: keyring.address,
  account: caver.account.createWithAccountKeyPublic(
    keyring.address,
    key.publicKey
  ),
  gas: 1000000,
});

// 트랜잭션에 서명합니다.
await keyringContainer.sign(keyring.address, updateTx);

const result = {
  keyId: key.keyId,
  address: keyring.address,
  rlp: updateTx.getRLPEncoding(),
};
Copy
Copied
// Klaytn 계정을 KAS Wallet API로 마이그레이션하기 위해서는 트랜잭션을 생성하고 이를 서명하여 KAS로 전송해야 합니다.
// 트랜잭션에 서명하기 위해 Klaytn 계정으로 Keyring 인스턴스를 생성하고 해당 Keyring 인스턴스를 트랜잭션에 서명할 때 파라미터로 넘겨줍니다.
// 만약 Klaytn 계정의 키가 `AccountKeyWeigthedMultiSig`이거나 `AccountKeyRoleBased`인 경우
// `KeyringFactory.create` 의 두 번째 파라미터를 String[] 혹은 List<String[]>로 넘기면 됩니다.
// 더욱 자세한 내용은 https://javadoc.io/doc/com.klaytn.caver/core/latest/com/klaytn/caver/wallet/keyring/KeyringFactory.html 를 참고해 주세요.

AbstractKeyring keyring = KeyringFactory.create("0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3", "0x{private key}");

// KAS Wallet API에 키를 생성합니다.
// `caver.kas.wallet.createKeys`를 통해 리턴되는 값의 형태는 아래와 같습니다.
// {
//     items: [
//         { blob: '0x06000...', keyId: 'krn:1001:...', krn: 'krn:1001:...', publicKey: '0x0400e...', },
//     ],
// }
KeyCreationResponse keyCreationResponse = caver.kas.wallet.createKeys(1);
List<Key> createdKeys = keyCreationResponse.getItems();
Key key = createdKeys.get(0);

// FeeDelegatedAccountUpdate 트랜잭션을 생성합니다.
// account 필드에 할당되는 값은 `caver.account.createWithAccountKeyPublic`를 사용하여 생성할 수 있으며
// 마이그레이션 하고자 하는 계정의 주소, 그리고 KAS Wallet API에 생성된 키(public key string 형태)를 파라미터로 전달해야 합니다.
FeeDelegatedAccountUpdate updateTx = caver.transaction.feeDelegatedAccountUpdate.create(
        TxPropertyBuilder.feeDelegatedAccountUpdate()
                .setFrom(keyring.getAddress())
                .setAccount(
                        caver.account.createWithAccountKeyPublic(
                                keyring.getAddress(),
                                key.getPublicKey()
                        )
                )
                .setGas(BigInteger.valueOf(1000000))
);

// 트랜잭션에 서명합니다.
updateTx.sign(keyring);

System.out.println("keyId: " + key.getKeyId());
System.out.println("address: " + keyring.getAddress());
System.out.println("rlp: " + updateTx.getRLPEncoding());

계정 마이그레이션

이전 섹션에서 만들어진 계정 업데이트 트랜잭션의 결과를 이용하여 계정 마이그레이션을 수행합니다. API 호출에 앞서 이전 섹션의 결과값을 상기해보면 아래와 같습니다.

Copy
Copied
{
  "keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
  "address": "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
  "rlp": "0x...."
}

API 호출

Copy
Copied
curl --location --request POST 'https://wallet-api.klaytnapi.com/v2/registration/account' \
--header 'x-chain-id: 1001' \
-u {access-key-id}:{secret-access-key} \
--header 'Content-Type: application/json' \
--data-raw '[
{
    "keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
    "address": "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
    "rlp": "0x..."
}
]'

API 응답

cURLcURL
Copy
Copied
// 성공
{
  "status": "ok"
}
Copy
Copied
// 실패
{
  "failures": {
    "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3": "failed to send a raw transaction to klaytn node; -32000::invalid transaction v, r, s values of the sender"
  },
  "status": "all failed"
}

이 API에 관한 자세한 내용은 다음을 확인하십시오.
이 문서 혹은 KAS에 관한 문의는 개발자 포럼을 방문해 도움 받으십시오.