Nếu bạn dùng một phiên bản khác của Node (ví dụ như Node v15), hãy dùng Trình quản lý phiên bản Node (nvm) để cài đặt và sử dụng phiên bản được caver-js hỗ trợ.
Cài đặt
Để thử dùng, hãy cài đặt caver-js với npm bằng cách dùng lệnh sau:
$ npm install caver-js
Lưu ý: tập tin package.json phải tồn tại trên cùng một đường dẫn cài đặt. Nếu nó không tồn tại, package.json có thể được tạo qua npm init.
Để cài đặt một phiên bản caver-js cụ thể, hãy thử lệnh sau:
$ npm install caver-js@X.X.X
Bắt đầu với caver-js
Khi đã cài xong caver-js, bạn có thể kết nối với một nút Klaytn bằng caver-js.
Để thực hành các ví dụ dưới đây, trước tiên, hãy tạo một tập tin thử nghiệm trong thư mục làm việc.
$touchtest.js
Bạn có thể thấy tập tin test.js được tạo ra trong thư mục làm việc.
Nếu bạn thấy kết quả đầu ra của console.log như trên, hãy tiếp tục với các bước dưới đây. Số phiên bản có thể sẽ khác theo phiên bản của nút Klaytn được kết nối.
Kết nối với một Nút Klaytn
Bạn có thể nhập mô-đun caver-js và kết nối nó với một Nút Klaytn trong mạng thử nghiệm Baobab như trong ví dụ dưới đây:
Keyring là một cấu trúc chứa địa chỉ của một tài khoản Klaytn và (các) khóa riêng tư.
Keyring có thể được phân thành ba loại tùy thuộc vào loại khóa được lưu trữ: SingleKeyring chứa một địa chỉ và một khóa riêng tư, MultipleKeyring chứa một địa chỉ và nhiều khóa riêng tư và RoleBasedKeyring chứa một địa chỉ và một hoặc nhiều khóa riêng tư cho từng vai trò.
SingleKeyring xác định thuộc tính key bên trong, và key này chứa một khóa riêng tư.
MultipleKeyring xác định thuộc tính keys bên trong, và keys này được triển khai dưới dạng một mảng để chứa nhiều khóa riêng tư.
Thuộc tính keys được xác định trong RoleBasedKeyring được triển khai dưới dạng một mảng hai chiều (keys trống có dạng [ [], [], [] ]) có thể bao gồm nhiều khóa cho từng [role](../../../klaytn/design/tài khoảns.md#roles). Phần tử đầu tiên của mảng này chứa (các) khóa riêng tư để sử dụng cho roleTransactionKey, phần tử thứ hai là (các) khóa riêng tư để sử dụng cho roleAccountUpdateKey, và phần tử thứ ba là (các) khóa riêng tư để sử dụng cho roleFeePayerKey.
Tạo một Keyring
Tạo một SingleKeyring
Bạn có thể tạo ngẫu nhiên một keyring đơn lẻ như dưới đây.
Kết quả thực thi được hiển thị ở trên. Các biến thành viên được xác định bên trong đối tượng cụ thể có thể được truy cập qua keyring.address và keyring.key.
Tạo một SingleKeyring từ khóa riêng tư
Ngoài ra, nếu bạn sở hữu một khóa riêng tư cụ thể, bạn có thể sử dụng khóa này để tạo một keyring như bên dưới.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create a keyring from a private keyconstkeyringFromPrivateKey=caver.wallet.keyring.createFromPrivateKey('0x{private key}')console.log(keyringFromPrivateKey)}testFunction()
Kết quả của caver.wallet.keyring.createFromPrivateKey, cũng như kết quả của caver.wallet.keyring.generate ở trên, là một đối tượng SingleKeyring cụ thể với một địa chỉ được xác định bên trong nó, và một đối tượng [PrivateKey] cụ thể trong keyring.key.
Tạo một SingleKeyring bằng một khóa riêng tư và một địa chỉ
Nếu khóa riêng tư cho tài khoản Klaytn của bạn tách rời khỏi địa chỉ, bạn có thể tạo một keyring bằng địa chỉ đã cho và khóa riêng tư đã cho như dưới đây.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create a keyring with an address and a private keyconstkeyring=caver.wallet.keyring.createWithSingleKey('0x{address in hex}','0x{private key}')console.log(keyring)// Create a keyring from a KlaytnWalletKeyconstkeyringFromKlaytnWalletKey=caver.wallet.keyring.createFromKlaytnWalletKey('0x{private key}0x{type}0x{address in hex}')console.log(keyringFromKlaytnWalletKey)}testFunction()
Nếu bạn muốn dùng nhiều khóa riêng tư, bạn có thể tạo một MultipleKeyring bằng một địa chỉ và nhiều khóa riêng tư. Các ví dụ dưới đây cho thấy cách để tạo ra một MultipleKeyring bằng nhiều khóa riêng tư.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create a keyring with an address and private keysconstkeyring=caver.wallet.keyring.createWithMultipleKey('0x{address in hex}', [ '0x{private key1}','0x{private key2}' ])console.log(keyring)}testFunction()
Như bạn có thể thấy, _keys có nhiều đối tượng PrivateKey cụ thể trong mảng. Các biến thành viên được xác định bên trong đối tượng cụ thể có thể được truy cập qua keyring.address và keyring.keys.
Tạo một RoleBasedKeyring bằng các khóa riêng tư
Để sử dụng (các) khóa riêng tư cho từng [role](../../../klaytn/design/tài khoảns.md#roles), caver.wallet.keyring.createWithRoleBasedKey sẽ được dùng. Mỗi phần tử trong mảng tương ứng với một vai trò được mô tả trong RoleBasedKeyring. Ví dụ dưới đây hướng dẫn cách tạo ra một đối tượng RoleBasedKeyring cụ thể từ các khóa khác nhau cho từng vai trò.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create a keyring with an address and private keys defined by each rolesconstkeyring=caver.wallet.keyring.createWithRoleBasedKey('0x{address in hex}', [ [ '0x{private key1}','0x{private key2}','0x{private key3}' ], [ '0x{private key4}'], [ '0x{private key5}','0x{private key6}' ], ])console.log(keyring)}testFunction()
Nhìn vào kết quả trên, phần tử đầu tiên của mảng khóa roleTransactionKey có ba đối tượng PrivateKey cụ thể, và phần tử thứ hai, roleAccountUpdateKey có một đối tượng PrivateKey cụ thể. Và phần tử cuối cùng của mảng, roleFeePayerKey, có hai đối tượng PrivateKey cụ thể.
Lưu ý: Việc gọi các hàm liên quan đến keyring (caver.wallet.keyring) hoặc ví (caver.wallet) không làm ảnh hưởng đến nền tảng chuỗi khối Klaytn thực tế (Klaytn).
Thêm Keyring vào caver-js
Bạn có thể dễ dàng dùng một keyring bằng cách sử dụng ví trong bộ nhớ mà caver-js cung cấp. Các ví dụ dưới đây minh họa cách để thêm một keyring vào ví bằng một đối tượng keyring cụ thể và một tập tin lưu trữ khóa được tạo ra bởi Ví Klaytn.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Using a keyring instanceconstkeyring=caver.wallet.keyring.generate()caver.wallet.add(keyring)console.log(caver.wallet.getKeyring(keyring.address))// Using a keystore fileconstdecrypted=caver.wallet.keyring.decrypt({ version:4, id:'9c12de05-0153-41c7-a8b7-849472eb5de7', address:'0xc02cec4d0346bf4124deeb55c5216a4138a40a8c', keyring: [ { ciphertext:'eacf496cea5e80eca291251b3743bf93cdbcf7072efc3a74efeaf518e2796b15', cipherparams: { iv:'d688a4319342e872cefcf51aef3ec2da' }, cipher:'aes-128-ctr', kdf:'scrypt', kdfparams: { dklen:32, salt:'c3cee502c7157e0faa42386c6d666116ffcdf093c345166c502e23bc34e6ba40', n:4096, r:8, p:1 }, mac:'4b49574f3d3356fa0d04f73e07d5a2a6bbfdd185bedfa31f37f347bc98f2ef26' } ] },'password')caver.wallet.add(decrypted)console.log(caver.wallet.getKeyring(decrypted.address))}testFunction()
Nhìn vào kết quả đầu ra ở trên, bạn có thể truy vấn keyring của mình từ caver.wallet sau khi thêm nó vào caver.wallet.
Nếu bạn có một địa chỉ và (các) khóa riêng tư để dùng, bạn có thể dễ dàng tạo ra một keyring và trực tiếp thêm nó vào caver.wallet thông qua caver.wallet.newKeyring.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Add to wallet with an address and a private keyconstaddedSingle=caver.wallet.newKeyring('0x{address in hex}','0x{private key1}')console.log(caver.wallet.getKeyring(addedSingle.address))// Add to wallet with an address and private keysconstaddedMultiple=caver.wallet.newKeyring('0x{address in hex}', ['0x{private key2}','0x{private key3}','0x{private key4}'])console.log(caver.wallet.getKeyring(addedMultiple.address))// Add to wallet with an address and private keys defined by each rolesconstaddedRoleBased=caver.wallet.newKeyring('0x{address in hex}', [ ['0x{private key5}','0x{private key6}','0x{private key7}'], ['0x{private key8}','0x{private key9}'], ['0x{private key10}','0x{private key11}'] ])console.log(caver.wallet.getKeyring(addedRoleBased.address))}testFunction()
Khi chạy mã trên, bạn sẽ nhận được kết quả sau. Kết quả của việc thực thi mã trên được hiển thị dưới đây. Khi caver.wallet.newKeyring được thực thi với một khóa riêng tư, một đối tượng Keyring cụ thể với một khóa riêng tư sẽ được tạo ra và thêm vào caver.wallet. Đối với nhiều khóa riêng tư, một đối tượng Keyring cụ thể với nhiều khóa riêng tư sẽ được tạo ra. Khi dùng một hoặc nhiều khóa riêng tư làm đối số cho từng vai trò, một phiên bản Keyring với (các) khóa riêng tư khác nhau cho từng vai trò sẽ được tạo ra và thêm vào caver.wallet.
caver.wallet.add hoặc caver.wallet.newKeyring trả về một đối tượng Keyring cụ thể sau khi đã thêm nó vào caver.wallet.
Gửi giao dịch
Phần này sẽ hướng dẫn bạn các để gửi KLAY bằng caver-js trên mạng Baobab.
Nhận KLAY qua Vòi Baobab
Nếu bạn cần KLAY để thử nghiệm, bạn có thể nhận KLAY dùng trong mạng thử nghiệm Baobab từ Ví Klaytn. Hãy đăng nhập vào Ví Wallet bằng khóa riêng tư hoặc tập tin lưu trữ khóa, và nhận KLAY dùng cho mạng thử nghiệm Baobab qua vòi để thử nghiệm.
Gửi một giao dịch chuyển giá trị
Bạn có thể sử dụng ví caver-js để tạo chữ ký của giao dịch. Bạn sẽ phải thực hiện hai bước dưới đây để gửi giao dịch đến mạng lưới.
Ký giao dịch
Nếu keyring mà bạn muốn dùng đã được thêm vào caver.wallet, bạn có thể dùng hàm caver.wallet.sign để ký.
Nếu bạn quản ký keyring riêng biệt và không thêm nó vào caver.wallet, bạn có thể ký giao dịch thông qua hàm transaction.sign.
Gửi chuỗi mã hóa RLP của giao dịch đã ký đến Klaytn qua caver.rpc.klay.sendRawTransaction.
Lưu ý: Người gửi phải có đủ lượng KLAY.
Ký giao dịch
Trước khi gửi một giao dịch đến Klaytn, bạn phải ký giao dịch trước.
Dưới đây là ví dụ về cách ký một giao dịch trong trường hợp một keyring đã được thêm vào caver.wallet.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Add a keyring to caver.walletconstkeyring=caver.wallet.keyring.createFromPrivateKey('0x{private key}')caver.wallet.add(keyring)// Create a value transfer transactionconstvalueTransfer=caver.transaction.valueTransfer.create({ from:keyring.address, to:'0x176ff0344de49c04be577a3512b6991507647f72', value:1, gas:30000, })// Sign the transaction via caver.wallet.signawaitcaver.wallet.sign(keyring.address, valueTransfer)constrlpEncoded=valueTransfer.getRLPEncoding()console.log(`RLP-encoded string: ${rlpEncoded}`)}testFunction()
Mã trên thêm một keyring vào caver.wallet, tạo ra một giao dịch và ký giao dịch đó qua caver.wallet.sign.
Khi chạy mã trên, bạn sẽ nhận được kết quả sau. Khi mã trên đã được thực thi, chuỗi mã hóa RLP của giao dịch sẽ hiển thị dưới đây. (Kết quả chuỗi mã hóa RLP mà bạn nhận được có thể khác với kết quả chuỗi hiển thị dưới đây).
Gửi chuỗi mã hóa RLP của giao dịch đã ký đến Klaytn
Giờ bạn có thể gửi một giao dịch đã ký đến mạng lưới như dưới đây. Nếu bạn muốn chạy thử ví dụ bên dưới, hãy thay thế 0x{RLP-encoded string} bằng giá trị của rlpEncoded ở trên.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constrlpEncoding=`0x{RLP-encoded string}`// Send the transaction using `caver.rpc.klay.sendRawTransaction`.constreceipt=awaitcaver.rpc.klay.sendRawTransaction(rlpEncoding)console.log(receipt)}testFunction()
Khi chạy mã trên, bạn sẽ nhận được kết quả sau. Khi mã trên đã được thực thi, biên lai của giao dịch sẽ hiển thị dưới đây.
Nếu bạn muốn ký một giao dịch và gửi nó đến mạng lưới mà không cần caver.wallet, hãy xem ví dụ bên dưới.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create a value transfer transactionconstkeyring=caver.wallet.keyring.createFromPrivateKey('0x{private key}')constvalueTransfer=caver.transaction.valueTransfer.create({ from:keyring.address, to:'0x176ff0344de49c04be577a3512b6991507647f72', value:1, gas:30000, })// Sign the transaction via transaction.signawaitvalueTransfer.sign(keyring)// Send the transaction to the Klaytn using `caver.rpc.klay.sendRawTransaction`.constreceipt=awaitcaver.rpc.klay.sendRawTransaction(valueTransfer)console.log(receipt)}testFunction()
Khi mã trên được triển khai, biên lai của giao dịch sẽ hiển thị ra màn hình như ví dụ trước đó.
Kiểm tra biên lai
Bạn có thể dùng đối tượng promise hoặc lớp phát sinh sự kiện để nhận biên lai của giao dịch khi chuyển giao dịch đó đến Klaytn bằng caver.rpc.klay.sendRawTransaction.
Ví dụ dưới đây cho thấy cách để nhận biên lai bằng các đối tượng promise và lớp phát sinh sự kiện.
// Using a promise - async/awaitconstreceipt=awaitcaver.rpc.klay.sendRawTransaction(rawTransaction)console.log(receipt)// Using a promisecaver.rpc.klay.sendRawTransaction(rawTransaction).then(console.log)// Using an event emittercaver.rpc.klay.sendRawTransaction(rawTransaction).on('receipt',console.log)
Như mô tả trong ví dụ trên, bạn có thể nhận được kết quả của việc gửi giao dịch thông qua đối tượng promise hoặc lớp phát sinh sự kiện. Trường transactionHash được xác định bên trong đối tượng biên lai. Bạn có thể dùng phương pháp gọi RPC caver.rpc.klay.getTransactionReceipt kèm theo receipt.transactionHash để truy vấn biên lai của một giao dịch vào bất kỳ lúc nào từ mạng lưới sau khi giao dịch đã được đưa vào một khối. Ví dụ dưới đây cho thấy cách để lấy biên lai bằng cách gọi RPC caver.rpc.klay.getTransactionReceipt.
Bạn có thể tìm thấy kết quả của giao dịch qua trạng thái của biên lai. Để biết thêm chi tiết về các giá trị trả về, hãy xem caver.rpc.klay.getTransactionReceipt. Nếu một giao dịch thất bại, bạn có thể kiểm tra thêm thông tin về lỗi tại txError của biên lai. Để biết thêm thông tin về txError, hãy xem txError: Thông tin chi tiết về các lỗi giao dịch.
Thực thi các loại giao dịch khác
Klaytn cung cấp nhiều loại giao dịch đa dạng để đẩy mạnh khả năng mở rộng và hiệu suất. Để biết thêm thông tin, hãy xem Giao dịch. Mục này mô tả một số ví dụ mà bạn có thể sử dụng với caver-js.
Ủy thác phí
Klaytn cung cấp tính năng Ủy thác phí. Đây là một ví dụ về việc thực hiện một giao dịch mã hóa RLP khi bạn là người gửi loại giao dịch này:
Khi mã trên được thực thi, chuỗi mã hóa RLP sẽ được hiển thị ra màn hình. (Kết quả chuỗi mã hóa RLP mà bạn nhận được có thể khác với kết quả chuỗi hiển thị dưới đây).
Người trả phí có thể gửi giao dịch đến Klaytn sau khi đính kèm feePayerSignatures vào chuỗi mã hóa RLP (rawTransaction) được ký bởi người gửi giao dịch. Nếu caver.wallet cũng có khóa của người trả phí, chữ ký của người trả phí có thể được đưa vào feeDelegatedTx bằng cách gọi caver.wallet.signAsFeePayer(feePayer.address, feeDelegatedTx). Nếu không, người trả phí sẽ phải tạo feeDelegatedTx từ chuỗi mã hóa RLP được người gửi ký, sau đó thêm chữ ký của người trả phí vào đó như được minh họa dưới đây. Nếu bạn muốn chạy thử ví dụ bên dưới, hãy thay thế 0x{RLP-encoded string} bằng giá trị của rlpEncoded ở trên.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constfeePayer=caver.wallet.keyring.createFromPrivateKey('0x{private key}')caver.wallet.add(feePayer)constrlpEncoded='0x{RLP-encoded string}'constfeeDelegateTxFromRLPEncoding=caver.transaction.feeDelegatedValueTransfer.create(rlpEncoded)// Set the fee payer address.feeDelegateTxFromRLPEncoding.feePayer =feePayer.addressawaitcaver.wallet.signAsFeePayer(feePayer.address, feeDelegateTxFromRLPEncoding)console.log(feeDelegateTxFromRLPEncoding.getRLPEncoding())}testFunction()
Khi mã trên được thực thi, chuỗi mã hóa RLP bao gồm cả chữ ký của người gửi và người trả phí sẽ hiển thị ra màn hình như dưới đây. (Kết quả mà bạn nhận được có thể khác với kết quả chuỗi hiển thị dưới đây).
Lúc này, giao dịch đã được cả người gửi và người trả phí ký tên, và giờ nó có thể được gửi đến mạng lưới. Thay thế 0x{RLP-encoded string} bằng kết quả đầu ra chuỗi mã hóa RLP của mã ví dụ ở trên.
Nếu bạn muốn thay đổi (các) khóa riêng tư cho tài khoản Klaytn của mình, có 3 điều quan trọng mà bạn cần ghi nhớ:
Klaytn xác thực mọi giao dịch mà bạn gửi đến.
Quy trình xác thực yêu cầu sử dụng các khóa công khai tương ứng chính xác với (các) khóa riêng tư của bạn.
Vì thế, việc thay đổi (các) khóa riêng tư thành (các) khóa riêng tư mới sẽ luônkéo theo việc thay đổi (các) khóa công khai cũ thành (các) khóa mới. (Các) khóa công khai mới phải được lấy từ (các) khóa riêng tư mới.
Khi đã ghi nhớ 3 điều trên, bạn có thể thay đổi (các) khóa riêng tư của mình bằng cách thực hiện những bước sau:
Chuẩn bị (các) khóa riêng tư mới để tạo một keyring mới.
Tạo một keyring theo loại (Single keyring, Multiple keyring hoặc Role-based keyring) mà bạn cần.
Tạo một đối tượng Tài khoản cụ thể từ keyring mới. Đối tượng Tài khoản cụ thể này giữ (các) khóa công khai mới cho tài khoản Klaytn của bạn.
Gửi giao dịch AccountUpdate bao gồm cả đối tượng Tài khoản cụ thể đến Klaytn.
Cuối cùng, thay thế keyring cũ bằng keyring mới mà bạn tạo ở Bước 2.
Vui lòng xem [Cập nhật tài khoản](api-references/caver.transaction/basic.md#tài khoảnupdate) để biết thêm chi tiết.
Để thay đổi AccountKey của mình, bạn phải cung cấp một đối tượng [Tài khoản](api-references/caver.tài khoản.md) cụ thể cho trường tài khoản trong đối tượng đối số đầu vào của caver.transaction.tài khoảnUpdate. Một đối tượng [Account](api-references/caver.tài khoản.md) cu thể có chứa địa chỉ của tài khoản Klaytn và AccountKey cần được cập nhật.
Mã dưới đây là một mã ví dụ dùng để thay đổi (các) khóa riêng tư mà bạn dùng cho tài khoản Klaytn của mình, kèm theo việc thay đổi AccountKey của tài khoản Klaytn thành [AccountKeyPublic](../../../klaytn/design/tài khoảns.md#tài khoảnkeypublic). Đừng quên chuẩn bị (các) khóa riêng tư mới.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {let sender =caver.wallet.keyring.createFromPrivateKey('0x{private key}')caver.wallet.add(sender)constnewPrivateKey=caver.wallet.keyring.generateSingleKey()console.log(`new private key string: ${newPrivateKey}`)constnewKeyring=caver.wallet.keyring.createWithSingleKey(sender.address, newPrivateKey)// create an Account instanceconsttài khoản =newKeyring.toAccount()constupdateTx=caver.transaction.tài khoảnUpdate.create({ from:sender.address, tài khoản: tài khoản, gas:50000, })awaitcaver.wallet.sign(sender.address, updateTx)constreceipt=awaitcaver.rpc.klay.sendRawTransaction(updateTx)console.log(receipt)// Update the keyring in caver.wallet for signing afterward. sender =caver.wallet.updateKeyring(newKeyring)}testFunction()
Nếu mã trên được thực thi thành công, bạn sẽ không còn có thể dùng (các) khóa riêng tư cũ để ký bất kỳ giao dịch nào với keyring cũ nữa. Vì thế, bạn phải cập nhật keyring cũ bằng newKeyring thông qua caver.wallet.updateKeyring(newKeyring). Khi đã được cập nhật, (các) khóa riêng tư mới được cập nhật sẽ được dùng để ký.
Khi chạy mã trên, bạn sẽ nhận được kết quả sau. Trong kết quả thực thi của mã trên, kết quả của khóa riêng tư và cập nhật tài khoản mà bạn cần dùng thay thế được hiển thị ra màn hình như dưới đây.
Sau đây là hướng dẫn về cách cập nhật AccountKey của tài khoản Klayt có nhiều [AccountKeys]? Ví dụ dưới đây giải thích về cách để tạo một đối tượng [Account](api-references/caver.tài khoản.md) cụ thể với nhiều khóa riêng tư mà bạn muốn sử dụng (Bạn có thể tạo một đối tượng [Account](api-references/caver.tài khoản.md) cụ thể với nhiều khóa công khai qua [caver.tài khoản.create](api-references/caver.tài khoản.md#caver-tài khoản-create)). Tương tự như trên, sau khi nạp đối tượng tài khoản cụ thể vừa tạo ra vào trường tài khoản bên trong đối tượng giao dịch, phần còn lại của quá trình cập nhật cũng giống như ví dụ ở trên.
Trước tiên, hãy dùng tạo một đối tượng Tài khoản cụ thể để cập nhật bằng [AccountKeyWeightedMultiSig](../../../klaytn/design/tài khoảns.md#tài khoảnkeyweightedmultisig). Đối với [AccountKeyWeightedMultiSig](../../../klaytn/design/tài khoảns.md#tài khoảnkeyweightedmultisig), phải xác định ngưỡng và trọng số của từng khóa. Để thực hiện điều này, hãy dùng [caver.tài khoản.weightedMultiSigOptions](api-references/caver.tài khoản.md#weightedmultisigoptions). Tham số đầu tiên là ngưỡng, và tham số thứ hai là mảng có chứa trọng số cho từng khóa.
// Create an tài khoản instance with three private keys using AccountKeyWeightedMultiSigconstnewPrivateKeys=caver.wallet.keyring.generateMultipleKeys(3)constnewKeyring=caver.wallet.keyring.createWithMultipleKey(sender.address, newPrivateKeys)// threshold = 3, the weights of the three keys = [1, 2, 1]constoptions=newcaver.tài khoản.weightedMultiSigOptions(3, [1,2,1])consttài khoản =newKeyring.toAccount(options)
Bây giờ, hãy cập nhật AccountKey bằng [AccountKeyRoleBased](../../../klaytn/design/tài khoảns.md#tài khoảnkeyrolebased). [AccountKeyRoleBased](../../../klaytn/design/tài khoảns.md#tài khoảnkeyrolebased) là một loại AccountKey xác định khóa để dùng cho từng [role](../../../klaytn/design/tài khoảns.md#roles).
// Create an tài khoản instance with roles using AccountKeyRoleBased. Trong đối tượng tài khoản cụ thể được tạo ra, mỗi vai trò có một khóa công khai tương ứng với một khóa riêng tư.constnewPrivateKeys=caver.wallet.keyring.generateRoleBasedKeys([1,1,1])constnewKeyring=caver.wallet.keyring.createWithRoleBasedKey(sender.address, newPrivateKeys)consttài khoản =newKeyring.toAccount()
AccountKeyRoleBased ở trên là một ví dụ về việc sử dụng một khóa công khai cho từng vai trò. Như có thể thấy từ mã trên, từng vai trò tương ứng với một khóa riêng tư. Nếu bạn muốn dùng nhiều khóa riêng tư cho từng vai trò, [caver.tài khoản.weightedMultiSigOptions](api-references/caver.tài khoản.md#weightedmultisigoptions) phải được xác định cho từng vai trò như minh họa dưới đây.
// Create an tài khoản instance with [3, 2, 3] keys for each role using AccountKeyRoleBasedconstnewPrivateKeys=caver.wallet.keyring.generateRoleBasedKeys([3,2,3])constnewKeyring=caver.wallet.keyring.createWithRoleBasedKey(sender.address, newPrivateKeys)constoptions= [// thresold = 4, weights of keys = [2, 2, 4] for roleTransactionKeynewcaver.tài khoản.weightedMultiSigOptions(4, [2,2,4]),// threshold = 2, weights of keys = [1, 1]newcaver.tài khoản.weightedMultiSigOptions(2, [1,1]),// threshold = 3, weights of keys = [1, 1, 1]newcaver.tài khoản.weightedMultiSigOptions(3, [1,1,1]),]consttài khoản =newKeyring.toAccount(options)
Nếu bạn muốn cập nhật AccountKey thành [AccountKeyLegacy](../../../klaytn/design/tài khoảns.md#tài khoảnkeylegacy) hoặc [tài khoảnKeyFail](../../../klaytn/design/tài khoảns.md#tài khoảnkeyfail), hãy tạo một đối tượng Tài khoản cụ thể như minh họa dưới đây, và gán nó vào trường tài khoản của giao dịch.
// Create an tài khoản with AccountKeyLegacyconsttài khoảnWithLegacyKey =caver.tài khoản.createWithAccountKeyLegacy(keyringToUpdate.address)// Create an tài khoản with AccountKeyFailconsttài khoảnWithFailKey =caver.tài khoản.createWithAccountKeyFail(keyringToUpdate.address)
Hợp đồng thông minh
Gói caver.contract giúp việc tương tác với hợp đồng thông minh trên Klaytn trở nên dễ dàng hơn. Nó tự động chuyển đổi tất cả các phương pháp của hợp đồng thông minh thành những cuộc gọi javascript khi ABI mức độ thấp (Giao diện nhị phân ứng dụng) được đưa ra. Điều này cho phép bạn tương tác với các hợp đồng thông minh như thể chúng là các đối tượng JavaScript.
Trước tiên, chúng ta sẽ tạo một ví dụ đơn giản bằng ngôn ngữ solidity như dưới đây. Tạo tập tin "test.sol" và viết vào đó ví dụ dưới đây.
pragma solidity ^0.5.6;
contract KVstore {
mapping(string=>string) store;
function get(string memory key) public view returns (string memory) {
return store[key];
}
function set(string memory key, string memory value) public {
store[key] = value;
}
}
Bây giờ, chúng ta có thể lập một hợp đồng thông minh để lấy chỉ thị biên dịch và ABI của nó.
Nhìn vào kết quả đầu ra ở trên, bạn có thể thấy rằng các phương pháp được quản lý thông quan abi bên trong đối tượng Hợp đồng cụ thể. Và vì nó vẫn chưa được triển khai, bạn có thể thấy rằng kết quả của contractInstance.options.address có đầu ra là null.
Nếu hợp đồng thông minh đã được triển khai và bạn biết địa chỉ hợp đồng mà tại đó hợp đồng thông minh được triển khai, hãy dùng địa chỉ hợp đồng đó làm tham số thứ hai như dưới đây.
Vì phiên bản hợp đồng cụ thể này nhận được địa chỉ của hợp đồng thông minh, nó lưu trữ địa chỉ hợp đồng trong contractInstance.options.address.
Nếu phiên bản hợp đồng cụ thể được tạo ra, bạn có thể triển khai nó bằng cách đưa chỉ thị biên dịch vào trường data như dưới đây.
Lưu ý rằng caver.contract gửi các giao dịch để triển khai và thực thi. Nó dùng các keyring trong caver.wallet để ký các giao dịch. Keyring cần dùng phải được thêm vào caver.wallet từ trước.
Nếu bạn muốn gửi một giao dịch trong đó người gửi và người trả phí ký riêng biệt nhau khi triển khai một hợp đồng thông minh qua caver.contract, hãy tham khảo mã dưới đây:
Nếu bạn muốn gửi một giao dịch trong đó người gửi và người trả phí ký riêng biệt nhau khi thực thi một hợp đồng thông minh qua caver.contract, hãy tham khảo mã dưới đây:
Nếu AccountKey của tài khoản Klaytn là AccountKeyMultiSig hoặc AccountKeyRoleBased, có thể có nhiều người khác nhau quản lý từng khóa.
Phần này mô tả cách để thu thập nhiều chữ ký và gửi giao dịch nếu có nhiều người ký.
Để chạy ví dụ này, bạn cần cập nhật AccountKey của tài khoản Klaytn mà bạn dùng để thử nghiệm với [AccountKeyWeightedMultiSig](../../../klaytn/design/tài khoảns.md#tài khoảnkeyweightedmultisig). Vui lòng tham khảo [Cập nhật tài khoản ](getting-started.md#tài khoản-update) để xem cách cập nhật tài khoản Klaytn.
Ký tuần sự
Khi một giao dịch được ký bằng caver.wallet hoặc hàm sign của giao dịch, các chữ ký (hoặc feePayerSignatures) được xác định (hoặc thêm vào) bên trong giao dịch. Bạn có thể lấy chuỗi mã hóa RLP (rawTransaction) có chứa các chữ ký (và feePayerSignatures) bằng cách gọi hàm transaction.getRLPEncoding() của đối tượng giao dịch cụ thể được ký.
Ví dụ sau đây cho thấy cách để tuần tự ký một giao dịch với nhiều khóa riêng tư. Giả sử rằng AccountKey của tài khoản gửi giao dịch này là AccountKeyWeightedMultiSig của hai khóa công khai, điều này có nghĩa là tài khoản Klaytn này có thể dùng hai chuỗi khóa riêng tư, một khóa riêng tư cho từng người dùng. Đây là trường hợp có hai người dùng chia sẻ cùng một tài khoảng Klaytn.
Trong ví dụ dưới đây, user1 và user2 tạo ra các đối tượng Keyring cụ thể để sử dụng. Sau đó, mỗi người dùng keyring của riêng mình để ký giao dịch. Ví dụ dưới đây sử dụng transaction.sign để ký.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constuser1=caver.wallet.keyring.createWithSingleKey('0x{address in hex}','0x{private key1}')constuser2=caver.wallet.keyring.createWithSingleKey('0x{address in hex}','0x{private key2}')consttransaction=caver.transaction.valueTransfer.create({ from:user1.address, to:'0x45c2a1e3a1c3957a06dae73ad516461c2d2c7ccc', value:1, gas:70000, })awaittransaction.sign(user1)console.log(transaction.signatures)awaittransaction.sign(user2)console.log(transaction.signatures)}testFunction()
Khi chạy mã trên, bạn sẽ nhận được kết quả sau. Nhìn vào kết quả thực thi của mã trên, nếu user1 ký, một chữ ký sẽ được tạo ra. Nếu user2 ký, chữ ký của user2 sẽ được thêm vào. SignatureData là một đối tượng chứa một chữ ký.
Hãy cùng xem cách để ký tuần tự mà không cần chia sẻ cùng một đối tượng giao dịch. Trong ví dụ dưới đây, user1 gửi cho user2 chuỗi mã hóa RLP, chính là kết quả của hàm getRLPEncoding của giao dịch đã ký.
Mã dưới đây giải thích cách để ký và bổ sung chữ ký vào bằng chuỗi mã hóa RLP.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {// Create user1's keyringconstuser1=caver.wallet.keyring.createWithSingleKey('0x{address in hex}','0x{private key1}')// Create a value transfer transactionconsttransaction=caver.transaction.valueTransfer.create({ from:user1.address, to:'0x45c2a1e3a1c3957a06dae73ad516461c2d2c7ccc', value:1, gas:70000, })// Sign the transactionawaittransaction.sign(user1)// Create user2's keyringconstuser2=caver.wallet.keyring.createWithSingleKey('0x{address in hex}','0x{private key2}')// Create a value transfer transaction from the RLP-encoded stringconstrlpEncoding=transaction.getRLPEncoding()consttransactionFromRLP=caver.transaction.valueTransfer.create(rlpEncoding)awaittransactionFromRLP.sign(user2)console.log(transactionFromRLP.signatures)}testFunction()
Nếu chạy mã trên, bạn có thể thấy rằng chữ ký của user2 đã được đưa vào transactionFromRLP.signatures và trong đó có tổng cộng hai chữ ký.
Khi tất cả người dùng đã ký, hãy gửi giao dịch đến mạng lưới qua await caver.rpc.klay.sendRawTransaction(transactionFromRLP).
Nếu bạn gửi một giao dịch có phí ủy thác, và người trả phí dùng nhiều khóa, bạn có thể tiếp tục với logic trên bằng caver.wallet.signAsFeePayer.
Kết hợp các giao dịch thô đã ký
Nếu bạn nhận được nhiều chuỗi giao dịch thô mã hóa RLP đã ký từ nhiều người, bạn có thể kết hợp chúng thành một chuỗi giao dịch thô mã hóa RLP duy nhất có chứa tất cả các chữ ký.
Ví dụ dưới đây cho thấy cách để kết hợp và gửi các giao dịch mã hóa RLP.
Sau khi chạy mã trên, kết quả đầu ra sẽ là một chuỗi giao dịch thô mã hóa RLP có tất cả thông tin chữ ký được kết hợp.
Khi thực thi combineSignedRawTransactions, các chuỗi giao dịch thô mã hóa RLP đã ký cần được kết hợp phải giống hệt nhau, ngoại trừ các chữ ký và biến tùy chọn trong đối tượng giao dịch cụ thể. Các biến tùy chọn không có giá trị cho trước trong đối tượng giao dịch cơ sở cụ thể (đối tượng gọi của combineSignedRawTransactions) sẽ được quy đổi sang những biến tương ứng trong chuỗi giao dịch thô dưới đây để được hợp nhất ngay sau đó. Nếu phát sinh hiện tượng không nhất quán giữa các chuỗi giao dịch thô, bao gồm giá trị của các biến tùy chọn cần được hợp nhất, sẽ có lỗi xảy ra.
combineSignedRawTransactions trả về kết quả là một chuỗi mã hóa RLP có chứa tất cả các chữ ký (và feePayerSignatures nếu giao dịch là loại có phí ủy thác). Bạn dùng kết quả này để gửi một giao dịch đến mạng lưới qua await caver.rpc.klay.sendRawTransaction(combined).
Phát hiện sự triển khai các giao diện KCT
caver.kct cung cấp các hàm trả lại thông tin về giao diện mà hợp đồng token KCT nhất định triển khai. Với phương pháp này, bạn có thể thấy hợp đồng token KCT đã triển khai trên Klaytn áp dụng giao diện nào.
Phát hiện các giao diện KIP-7
Để phát hiện các giao diện được áp dụng bởi hợp đồng token KIP-7, bạn có thể dùng caver.kct.kip7.detectInterface(contractAddress) hoặc kip7.detectInterface().
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-7 được triển khai trên Klaytn nhờ các phương pháp tĩnh được cung cấp trong caver.kct.kip7.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constresult=awaitcaver.kct.kip7.detectInterface('0x{address in hex}')console.log(result)}testFunction()
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-7 được triển khai trên Klaytn nhờ phương pháp thành viên của KIP7.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constkip7=newcaver.kct.kip7('0x{address in hex}')constresult=awaitkip7.detectInterface()console.log(result)}testFunction()
Để phát hiện các giao diện được áp dụng bởi hợp đồng token KIP-17, bạn có thể dùng caver.kct.kip17.detectInterface(contractAddress) hoặc kip17.detectInterface().
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-17 được triển khai trên Klaytn nhờ các phương pháp tĩnh được cung cấp trong caver.kct.kip17.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constresult=awaitcaver.kct.kip17.detectInterface('0x{address in hex}')console.log(result)}testFunction()
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-17 được triển khai trên Klaytn nhờ phương pháp thành viên của KIP17.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constkip17=newcaver.kct.kip17('0x{address in hex}')constresult=awaitkip17.detectInterface()console.log(result)}testFunction()
Để phát hiện các giao diện được áp dụng bởi hợp đồng token KIP-37, bạn có thể dùng caver.kct.kip37.detectInterface(contractAddress) hoặc kip37.detectInterface().
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-37 được triển khai trên Klaytn nhờ các phương pháp tĩnh được cung cấp trong caver.kct.kip37.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constresult=awaitcaver.kct.kip37.detectInterface('0x{address in hex}')console.log(result)}testFunction()
Dưới đây là mã về cách để phát hiện các giao diện được áp dụng cho hợp đồng token KIP-37 được triển khai trên Klaytn nhờ phương pháp thành viên của KIP37.
// test.jsconstCaver=require('caver-js')constcaver=newCaver('https://public-en-baobab.klaytn.net/')asyncfunctiontestFunction() {constkip37=newcaver.kct.kip37('0x{address in hex}')constresult=awaitkip37.detectInterface()console.log(result)}testFunction()