Trong caver-java 1.5.0, chúng tôi áp dụng Common Architecture. Common Architecture là một kiến trúc phần mềm mới dành cho môi trường phát triển Klaytn, được chia sẻ bởi tất cả các SDK Klaytn (caver-js/caver-java). Kiến trúc này đươc thiết kế để đảm bảo trải nghiệm phát triển thuận lợi và khả năng mở rộng dễ dàng sang các ngôn ngữ lập trình khác.
Khi caver-java được cập nhật lên phiên bản 1.5.0, các API được dùng trong phiên bản 1.4.0 sẽ không còn hoạt động được nữa, ngoại trừ một số API.
Các API mới được cung cấp trong caver-java 1.5.0 như sau.
caver.tài khoản
caver.tài khoản là một gói dùng để cập nhật AccountKey, đó có thể là một hoặc nhiều khóa công khai (AccountKeyPublic, AccountKeyWeightedMultiSig và AccountKeyRoleBased) hoặc một loại khóa đặc biệt (AccountKeyLegacy và AccountKeyFail) cho một tài khoản Klaytn.
caver.tài khoản thay thế caver.tx.tài khoản trong caver-java 1.4.0
caver.wallet
caver.wallet là gói quản lý các đối tượng trong ví trong bộ nhớ. Keyring là một đối tượng cụ thể chứa địa chỉ của một tài khoản Klaytn và (các) khóa riêng tư của tài khoản đó, và nó được dùng khi địa chỉ của tài khoản này ký một giao dịch. caver.wallet chấp nhận tất cả các loại Keyring (SingleKeyring, MultipleKeyring và RoleBasedKeyring) và quản lý bằng địa chỉ tài khoản Klaytn của chúng.
caver.wallet thay thế caver.crypto trong caver-java 1.4.0
caver.wallet.KeyStore thay thế caver.wallet.WalletFile trong caver-java 1.4.0
caver.transaction
canver.transaction là một gói cung cấp chức năng liên quan đến Giao dịch.
caver.transaction thay thế caver.tx trong caver-java 1.4.0
caver.rpc
caver.rpc là một gói cung cấp chức năng liên quan đến việc thực hiện gọi rpc đến nút Klaytn.
caver.rpc.klay và caver.rpc.net lần lượt thay thế các giao diện Klay, Net trong caver-java 1.4.0
caver.util
caver.util cung cấp các chức năng tiện ích.
caver.contract
caver.contract là một gói giúp cho việc xử lý hợp đồng thông minh trong Klaytn trở nên dễ dàng hơn. Với caver.contract, bạn có thể triển khai và thực thi hợp đồng thông minh bằng cách gọi các hàm của chúng. caver.contract trước tiên sẽ chuyển đổi các hàm của hợp đồng thông minh và sự kiện từ ABI(Giao diện nhị phân ứng dụng), gọi các hàm đó và lấy thông tin sự kiện.
Điều kiện tiên quyết
Thêm kho dữ liệu
Một kho chứa dữ liệu thư viện cần phải được thêm vào trước khi sử dụng IPFS. Trước hết, vui lòng thêm kho dữ liệu sau.
Nếu bạn muốn dùng phần phụ thuộc Android, bạn chỉ cần thêm -android vào cuối chuỗi phiên bản. (ví dụ 1.0.1-android)
Nếu bạn muốn xem chi tiết của các yêu cầu và phản hồi JSON-RPC, vui lòng đưa phần phụ thuộc LOGBack vào dự án của mình. Dưới đây là một ví dụ về tập tin xây dựng Gradle. Bạn cũng có thể thêm phần phụ thuộc vào Maven. Vì caver-java sử dụng giao diện đăng nhập SLF4J, bạn có thể chuyển sang trình ghi bản ghi mà bạn thích thay cho LOGBack.
Lưu ý: Trong kho dữ liệu trung tâm, các phiên bản RC, Andriod và Java được liệt kê cùng nhau. Nếu bạn sử dụng ký tự đại diện để lấy một phiên bản, bạn có thể dùng phải một phiên bản không phù hợp với nền tảng của mình.
Công cụ dòng lệnh
Công cụ dòng lệnh cho phép bạn dùng dòng lệnh để tạo các lớp vỏ bọc chức năng bằng Solidity cho hợp đồng thông minh.
Cài đặt (Homebrew)
Cần có Java 1.8 trở lên để cài đặt công cụ này.
$ brew tap klaytn/klaytn
$ brew install caver-java
Sau khi cài đặt, bạn có thể chạy lệnh "caver-java" như dưới đây:
Hiện tại, chúng tôi không hỗ trợ các trình quản lý gói khác. Một giải pháp khác mà chúng tôi cung cấp là một phương pháp để xây dựng CLI như bên dưới.
Tải xuống hoặc tách luồng caver-java.
Dùng Gradle thực hiện tác vụ "shadowDistZip" trong mô-đun bảng điều khiển. Kết quả là console/build/distributions/console-shadow-{version}.zip được tạo ra.
Thực thi tập tin nhị phân để chạy công cụ dòng lệnh như dưới đây. Bạn có thể tìm thấy tập tin mã lập trình shell dành cho người dùng macOS và tập tin batch dành cho người dùng Window.
Phần này mô tả một ví dụ đơn giản về việc sử dụng tập tin kho khóa để gửi KLAY với một giao dịch chuyển giá trị. Tập tin kho khóa có thể được tạo ra trong Ví Klaytn. 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.
ublic voidsendingKLAY() throws IOException, CipherException, TransactionException {Caver caver =newCaver(Caver.BAOBAB_URL);//Read keystore json file.File file =newFile("./keystore.json");//Decrypt keystore.ObjectMapper objectMapper =ObjectMapperFactory.getObjectMapper();KeyStore keyStore =objectMapper.readValue(file,KeyStore.class);AbstractKeyring keyring =caver.wallet.keyring.decrypt(keyStore,"password");//Add to caver wallet.caver.wallet.add(keyring);BigInteger value =newBigInteger(caver.utils.convertToPeb(BigDecimal.ONE,"KLAY"));//Create a value transfer transactionValueTransfer valueTransfer =caver.transaction.valueTransfer.create(TxPropertyBuilder.valueTransfer().setFrom(keyring.getAddress()).setTo("0x8084fed6b1847448c24692470fc3b2ed87f9eb47").setValue(value).setGas(BigInteger.valueOf(25000)) );//Sign to the transactionvalueTransfer.sign(keyring);//Send a transaction to the klaytn blockchain platform (Klaytn)Bytes32 result =caver.rpc.klay.sendRawTransaction(valueTransfer.getRawTransaction()).send();if(result.hasError()) {thrownewRuntimeException(result.getError().getMessage()); }//Check transaction receipt.TransactionReceiptProcessor transactionReceiptProcessor =newPollingTransactionReceiptProcessor(caver,1000,15);TransactionReceipt.TransactionReceiptData transactionReceipt =transactionReceiptProcessor.waitForTransactionReceipt(result.getResult()); }
Bắt đầu với caver-java
Kết nối với một Nút Klaytn
Nếu bạn đang chạy một EN, bạn có thể kết nối nó với nút của riêng mình bằng cách thay đổi máy chủ và cổng như 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 theo loại khóa được lưu trữ: SingleKeyring lưu trữ một địa chỉ và một khóa riêng tư, MultipleKeyring lưu trữ một địa chỉ và nhiều khóa riêng tư, và RoleBasedKeyring lưu trữ 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 đối tượng Danh sách gồm 3 mảng chứa (các) khóa riêng tư như các phần tử trong đó (thuộc tính keys trống có dạng [ [], [], [] ]), như vậy, nó có thể chứa nhiều khóa cho từng vai trò. 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.
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.
String privateKey ="0x{private key in hex}";SingleKeyring keyring =caver.wallet.keyring.createFromPrivateKey(privateKey);
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.
String address ="0x{address in hex}";String privateKey ="0x{private key in hex}";SingleKeyring keyring =caver.wallet.keyring.createWithSingleKey(address, privateKey);
Ngoài ra, bạn có thể lấy đối tượng SingleKeyring cụ thể từ khóa của ví Klaytn.
String klaytnWalletKey ="0x{private key}0x{type}0x{address in hex}";SingleKeyring keyring =caver.wallet.keyring.createFromKlaytnWalletKey(klaytnWalletKey);
Tạo một MultipleKeyring bằng nhiều khóa riêng tư
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ư.
Để sử dụng (các) khóa riêng tư khác nhau cho từng role, 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ò.
String address ="0x{address in hex}";String[][] privateKeyArr =newString[][] {//roleTransactionKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },//roleAccountUpdateKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },//roleFeePayerKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },};RoleBasedKeyring keyring =caver.wallet.keyring.createWithRoleBasedKey(address,Arrays.asList(privateKeyArr));
Thêm các Keyring vào caver-java từ một chuỗi kho khóa json.
Bạn có thể sử dụng một keyring dễ dàng hơn bằng cách thêm nó vào ví trên bộ nhớ được caver-java cung cấp. Các ví dụ dưới đây minh họa cách để thêm một keyring vào caver.wallet bằng một chuỗi tập tin kho khóa JASON lưu trữ khóa được tạo ra bởi Ví Klaytn.
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.
Caver caver =newCaver(Caver.MAINNET_URL);// Add to wallet with an address and a private keyAbstractKeyring addedSingleKeyring =caver.wallet.newKeyring("0x{address in hex}","0x{private key1}");// Add to wallet with an address and private keysString[] privateKeyArr =newString[] {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}",};AbstractKeyring addedMultipleKeyring =caver.wallet.newKeyring('0x{address in hex}', privateKeyArr);// Add to wallet with an address and private keys defined by each rolesString[][] privateKeyArr =newString[][] {//roleTransactionKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },//roleAccountUpdateKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },//roleFeePayerKey {"0x{privateKey in hex}","0x{privateKey in hex}","0x{privateKey in hex}", },};AbstractKeyring addedRoleBased =caver.wallet.newKeyring('0x{address in hex}',Arrays.asList(privateKeyArr))
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 và thêm vào caver.wallet. Khi dùng một mảng chuỗi 2D làm dữ liệu đầu vào, bao gồm một hoặc nhiều khóa riêng tư cho mỗi vai trò với tư cách là một phần tử, một đối tượng Keyring cụ thể có chứa (các) khóa riêng tư khác nhau cho từng vai trò sẽ được tạo ra, và cũng được 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-java 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-java để 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 để chuyển và trả phí giao dịch.
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.
Caver caver =newCaver(Caver.MAINNET_URL);// Add a keyring to caver.walletSingleKeyring keyring =caver.wallet.keyring.createFromPrivateKey("privateKey");caver.wallet.add(keyring);// Create a value transfer transactionValueTransfer valueTransfer =caver.transaction.valueTransfer.create(TxPropertyBuilder.valueTransfer().setFrom(keyring.getAddress()).setTo("0x176ff0344de49c04be577a3512b6991507647f72").setValue(BigInteger.valueOf(1)).setGas(BigInteger.valueOf(30000)));// Sign the transaction via caver.wallet.signcaver.wallet.sign(keyring.getAddress(), valueTransfer);String rlpEncoded =valueTransfer.getRLPEncoding();System.out.println("RLP-encoded string: "+ rlpEncoded)
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ụ dưới đây, hãy thay thế "rlpEncoding" bằng giá trị của rlpEncoded trong mã bên trên.
publicStringsendRawTransaction() {Caver caver =newCaver(Caver.BAOBAB_URL);String rlpEncoding ="rlpEncoding";String txHash =null;try {// Send the transaction using `caver.rpc.klay.sendRawTransaction`.Bytes32 sendResult =caver.rpc.klay.sendRawTransaction(rlpEncoding).send();if(sendResult.hasError()) {//do something to handle error } txHash =sendResult.getResult(); } catch (IOException e) {// do something to handle exception }return txHash;}
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.
Caver caver =newCaver(Caver.MAINNET_URL);// Add a keyring to caver.walletSingleKeyring keyring =caver.wallet.keyring.createFromPrivateKey("privateKey");caver.wallet.add(keyring);// Create a value transfer transactionValueTransfer valueTransfer =caver.transaction.valueTransfer.create(TxPropertyBuilder.valueTransfer().setFrom(keyring.getAddress()).setTo("0x176ff0344de49c04be577a3512b6991507647f72").setValue(BigInteger.valueOf(1)).setGas(BigInteger.valueOf(30000)));// Sign the transaction via transaction.signvalueTransfer.sign(keyring);String rlpEncoded =valueTransfer.getRLPEncoding();try {// Send the transaction using `caver.rpc.klay.sendRawTransaction`.Bytes32 sendResult =caver.rpc.klay.sendRawTransaction(rlpEncoded).send();if(sendResult.hasError()) {//do something to handle error }String txHash =sendResult.getResult();System.out.println("Transaction Hash : "+ txHash);} catch (IOException e) {// do something to handle exception}
Khi mã trên được thực thi, hàm băm của giao dịch (txHash) được hiển thị ra màn hình như ví dụ dưới đây.
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 TransactionReceiptProcessor. 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 chuỗi txHash để 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.
Caver caver =newCaver(Caver.BAOBAB_URL);String txHash ="0x40552efbba23347d36f6f5aaba6b9aeb6602e004df62c1988d9b7b1f036e676a";try {TransactionReceipt receipt =caver.rpc.klay.getTransactionReceipt(txHash).send();if(receipt.hasError()) {// do something to handle error }TransactionReceipt.TransactionReceiptData receiptData =receipt.getResult();} catch (IOException e) {// do something to handle exception.}
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-java.
Ủ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ó keyring 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.
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.
Caver caver =newCaver(Caver.BAOBAB_URL);TransactionReceiptProcessor receiptProcessor =newPollingTransactionReceiptProcessor(caver,1000,15);String rlpEncoded ="0x{RLP-encoded string}";try {// Send the transaction using `caver.rpc.klay.sendRawTransaction`.Bytes32 sendResult =caver.rpc.klay.sendRawTransaction(rlpEncoding).send();if(sendResult.hasError()) {//do something to handle error }String txHash =sendResult.getResult();TransactionReceipt.TransactionReceiptData receiptData =receiptProcessor.waitForTransactionReceipt(txHash);} catch (IOException | TransactionException e) {// do something to handle exception.}
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].
Cập nhật tài khoả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 để 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 Account cụ thể cho trường tài khoản trong đối tượng đối số đầu vào của caver.transaction.type.AccountUpdate. Một đối tượng Tài khoản 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. Đừng quên chuẩn bị (các) khóa riêng tư mới.
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ý.
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 Tài khoản 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 Tài khoản cụ thể với nhiều khóa công khai qua 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. Đối với AccountKeyWeightedMultiSig, 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. 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 AccountKeyWeightedMultiSigString[] privateKeyArr =caver.wallet.keyring.generateMultipleKeys(3);MultipleKeyring multipleKeyring =caver.wallet.keyring.createWithMultipleKey(sender.getAddress(), privateKeyArr);// threshold = 3, the weights of the three keys = [1, 2, 1]BigInteger threshold =BigInteger.valueOf(3);BigInteger[] weightedArr =newBigInteger[] {BigInteger.valueOf(1),BigInteger.valueOf(2),BigInteger.valueOf(1)};WeightedMultiSigOptions options =newWeightedMultiSigOptions(threshold,Arrays.asList(weightedArr));Account tài khoản =multipleKeyring.toAccount(options)
Bây giờ, hãy cập nhật AccountKey bằng AccountKeyRoleBased. AccountKeyRoleBased là một loại AccountKey xác định khóa để dùng cho từng vai trò.
// 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ư.List<String[]> newPrivateKeyArr =caver.wallet.keyring.generateRolBasedKeys(newint[] {1,1,1});RoleBasedKeyring newKeyring =caver.wallet.keyring.createWithRoleBasedKey(senderKeyring.getAddress(), newPrivateKeyArr);const tà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 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 AccountKeyRoleBasedList<String[]> newPrivateKeyArr =caver.wallet.keyring.generateRolBasedKeys(newint[] {3,2,3});RoleBasedKeyring newKeyring =caver.wallet.keyring.createWithRoleBasedKey(senderKeyring.getAddress(), newPrivateKeyArr);WeightedMultiSigOptions[] options =newWeightedMultiSigOptions[] {newWeightedMultiSigOptions(BigInteger.valueOf(4),Arrays.asList(BigInteger.valueOf(2),BigInteger.valueOf(2),BigInteger.valueOf(4))),newWeightedMultiSigOptions(BigInteger.valueOf(2),Arrays.asList(BigInteger.valueOf(1),BigInteger.valueOf(1))),newWeightedMultiSigOptions(BigInteger.valueOf(3),Arrays.asList(BigInteger.valueOf(1),BigInteger.valueOf(1),BigInteger.valueOf(1))),};Account tài khoản =newKeyring.toAccount(Arrays.asList(options));
Nếu bạn muốn cập nhật AccountKey thành AccountKeyLegacy hoặc 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. Phần còn lại của quá trình cập nhật cũng tương tự như đối với AccountKey.
// Create an tài khoản with AccountKeyLegacyAccount tài khoản =caver.tàikhoản.createWithAccountKeyLegacy(keyringToUpdate.address);// Create an tài khoản with AccountKeyFailAccount tài khoản =caver.tàikhoản.createWithAccountKeyFail(keyringToUpdate.address)
Hợp đồng thông minh
Lớp Contract trong 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. Tất cả các hàm của một hợp đồng thông minh tự động được quy đổi và lưu trữ bên trong đối tượng contract cụ thể khi ABI mức thấp được đưa ra. Điều này cho phép bạn tương tác với hợp đồng thông minh như khi xử lý một đối tượng contract cụ thể trong Java.
Chúng ta sẽ bắt đầu giải thích về việc xử lý một hợp đồng thông minh trong Java bằng cách viết một mã ví dụ như dưới đây với Solidity. 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;
}
}
Sau đó, lập hợp đồng thông minh này để lấy bytecode và ABI của nó.
LƯU Ý: Để lập một hợp đồng thông minh, bạn phải cài đặt trước trình biên dịch solidity. Để biên dịch chương trình trên, bạn cần cài đặt solc:0.5.6.
Để triển khai một hợp đồng thông minh theo loại của nó, bạn có thể sử dụng các lớp caver-java được mô tả dưới đây:
Lớp Contract trong gói caver.contract khi người gửi hoặc người trả phí của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp SmartContractDeploy trong gói caver.transaction khi người gửi của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp feeDelegatedSmartContractDeploy trong gói caver.transaction khi người trả phí của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp feeDelegatedSmartContractDeployWithRatio trong gói caver.transaction khi người trả phí của một giao dịch hợp đồng thông mình thanh toán khoản phí
Dưới đây là một ví dụ về việc sử dụng lớp Contract trong gói caver.contract. Bạn có thể tạo một đối tượng contract cụ thể như dưới đây từ bytecode và ABI nhận được sau khi lập hợp đồng thông minh.
Nhìn vào kết quả trên, bạn có thể thấy rằng đối tượng contract cụ thể sở hữu phương pháp của hợp đồng thông minh. Và vì nó vẫn chưa được triển khai, bạn có thể thấy rằng kết quả của contract.getContractAddress() có đầu ra là null.
Nếu hợp đồng này đã được triển khai và bạn đã biết địa chỉ hợp đồng mà tại đó hợp đồng này được triển khai, hãy dùng địa chỉ hợp đồng như tham số thứ ba trong hàm tạo của đối tượng contract cụ thể như dưới đây.
Một đối tượng contract cụ thể chứa địa chỉ hợp đồng của mình dưới dạng thuộc tính contractAdress khi được tạo ra. Địa chỉ này có thể truy cập qua hàm getter / setter (getContractAddress() / setContractAddress()).
Khi một đối tượng contract cụ thể đã được tạo ra, bạn có thể triển khai hợp đồng thông minh bằng cách dùng chỉ thị biên dịch và các đối số của hàm tạo (khi cần dùng để triển khai) như ví dụ bên dưới.
Hãy lưu ý rằng phương pháp deploy() của đối tượng contract cụ thể gửi các giao dịch cho việc triển khai hợp đồng và thực thi hợp đồng. Đối với việc gửi giao dịch, nó sử dụng Keyrings trong caver.wallet để ký giao dịch. Keyring cần dùng phải được thêm vào caver.wallet trước khi ký.
Một hợp đồng thông minh có thể được triển khai bằng cách dùng một trong các lớp sau, tùy vào loại giao dịch triển khai hợp đồng:
Lớp Contract trong gói caver.contract khi người gửi hoặc người trả phí của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp SmartContractDeploy trong gói caver.transaction khi người gửi của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp feeDelegatedSmartContractDeploy trong gói caver.transaction khi người trả phí của một giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp feeDelegatedSmartContractDeployWithRatio trong gói caver.transaction khi người trả phí của một giao dịch hợp đồng thông mình thanh toán khoản phí
Để triển khai một hợp đồng thông minh qua một giao dịch ủy thác phí, hãy xác định các trường feeDelegation và feePayer trong lớp SendOptions như ví dụ 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 triển khai một hợp đồng thông minh qua caver.contract, hãy tham khảo mã dưới đây.
Để triển khai một hàm của hợp đồng thông minh theo loại của nó, bạn có thể dùng các lớp caver-java như được mô tả dưới đây:
Lớp Contract trong gói caver.contract khi người gửi giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp SmartContractExecution trong gói caver.transaction khi người gửi giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp FeeDelegatedSmartContractExecution trong gói caver.transaction khi người trả phí của giao dịch hợp đồng thông minh thanh toán khoản phí
Lớp FeeDelegatedSmartContractExecutionWithRatio trong gói canver.transaction khi người trả phí của giao dịch hợp đồng thông minh thanh toán khoản phí
Để xem cách thực thi một hàm trong hợp đồng thông minh, ở đây, chúng ta sẽ gửi đi một giao dịch thực thi hợp đồng dùng chuỗi "testValue" làm tham số đầu vào của hàm hợp đồng set như trong mã ví dụ dưới đây.
Để thực thi một hàm của hợp đồng thông minh thông qua giao dịch ủy thác phí, hãy xác định các trường feeDelegation và feePayer trong lớp SendOptions như ví dụ 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:
Để tải một đối tượng contract cụ thể và gọi một trong các hàm của nó (không gửi giao dịch đi mà chỉ gọi): ví dụ dưới đây minh họa việc gọi một hàm get trong hợp đồng.
IPFS (Hệ thống tập tin InterPlanetary) là một hệ thống tập tin phân tán, dùng để lưu trữ và truy cập các tập tin, trang web, ứng dụng và dữ liệu.
Bạn có thể tải lên và tải xuống một tập tin qua IPFS bằng Caver.
Kết nối với IPFS
Lớp IPFS trong gói caver.ipfs được xác định là một biến thành viên của lớp trong Caver, vì thế bạn có thể tương tác với IPFS qua Caver.
Để sử dụng một đối tượng IPFS cụ thể qua đối tượng Caver cụ thể, trước tiên, bạn phải gọi phương pháp setIPFSNode() để kết nối với một nút IPFS.
Hàm setIPFSNode() cần có các tham số sau:
URL của Máy chủ API theo giao thức HTTP dẫn đến IPFS
Số cổng của máy chủ API theo giao thức HTTP dẫn đến IPFS
Liệu máy chủ có dùng SSL hay không.
String host ="The URL of an IPFS node";int port =5001; // API host port numberboolean isSSL =true; // API host support ssl Caver caver =newCaver();caver.ipfs.setIPFSNode(host, port, isSSL);
Tải lên một tập tin qua IPFS
Để tải lên một tập tin qua IPFS, hãy dùng add() như dưới đây.
Kết quả thực thi của mã trên được hiển thị bên dưới.
QmYtUc4iTCbbfVSDNKvtQqrfyezPPnFvE33wFmutw9PBBk
Phát hiện giao diện KCT
Các hợp đồng KCT (Token tương thích với Klaytn) như KIP-7, KIP-17 và KIP-37 xác định và cung cấp nhiều giao diện đa dạng, và KIP-13 cho phép bạn xem liệu một hợp đồng có tuân thủ điều khoản quy định của KCT không, cũng như nó triển khai với giao diện nào bằng cách gửi một truy vấn đến hợp đồng.
KIP-13 đã được triển khai trong Caver v1.5.7. Nó có thể phát hiện giao diện thông qua detectInterface() cho bất kỳ lớp hợp đồng KCT nào (KIP7, KIP17 và KIP37).
Phát hiện các giao diện KIP-7
Để phát hiện các giao diện KIP-7, bạn có thể dùng detectInterface() trong lớp KIP7. Nó trả về ánh xạ giữa mã định danh giao diện KIP-7 và một boolean cho biết giao diện có được hỗ trợ hay không.
detectInterface() hỗ trợ cả phương pháp tĩnh và phương pháp đối tượng cụ thể, vì vậy, bạn có thể chọn và sử dụng phương pháp phù hợp với nhu cầu của mình.
Giao diện được phát hiện qua detectInterface() đối với KIP7 được thể hiện trong bảng dưới đây.
Để phát hiện giao diện được triển khai trong hợp đồng token KIP-17, bạn có thể dùng detectInterface() trong lớp KIP17. Nó trả về ánh xạ giữa mã định danh giao diện KIP-17 và sự hỗ trợ giao diện.
detectInterface() hỗ trợ cả phương pháp tĩnh và phương pháp đối tượng cụ thể, vì vậy, bạn có thể chọn và sử dụng phương pháp phù hợp với nhu cầu của mình.
Giao diện được phát hiện qua detectInterface() đối với KIP17 được thể hiện trong bảng dưới đây.
Để phát hiện giao diện được triển khai trong hợp đồng token KIP-37, bạn có thể dùng detectInterface() trong lớp KIP37. Nó trả về ánh xạ giữa mã định danh giao diện KIP-37 và sự hỗ trợ giao diện.
detectInterface() hỗ trợ cả phương pháp tĩnh và phương pháp đối tượng cụ thể, vì vậy, bạn có thể chọn và sử dụng phương pháp phù hợp.
Giao diện được phát hiện qua detectInterface() đối với KIP37 được thể hiện trong bảng dưới đây.