Tài khoản
Tài khoản Klaytn
Tổng quan về tài khoản, trạng thái và địa chỉ
Tài khoản trong Klaytn là một cấu trúc dữ liệu chứa thông tin về số dư của một người hoặc một hợp đồng thông minh. Trạng thái của Klaytn là tập hợp của tất cả các trạng thái của tài khoản trong đó - nghĩa là trạng thái trong quá khứ và hiện tại của tất cả các dữ liệu được lưu trữ trong tất cả các tài khoản của Klaytn. Khi một giao dịch được thực thi trên một nút Klaytn, thì kết quả là trạng thái của Klaytn sẽ thay đổi trên khắp tất cả các nút. Trạng thái của các nút trong mạng lưới Klaytn phải giống nhau nếu chúng đã xử lý các khối giống nhau có cùng thứ tự. Thông tin trạng thái của mỗi tài khoản được liên kết với địa chỉ 20 byte, địa chỉ này được dùng để định danh từng tài khoản.
Tách các cặp khóa khỏi địa chỉ
Một tài khoản là một nền tảng chuỗi khối điển hình liên kết với một địa chỉ đã xử lý mã hóa với độ dài nhất định, thường có dạng: "0x0fe2e20716753082222b52e753854f40afddffd2". Địa chỉ này được gắn chặt với một cặp khóa. Nếu đã chọn một cặp khóa, địa chỉ sẽ được lấy từ mã khóa công khai. Về mặt trải nghiệm người dùng, việc này có nhiều bất lợi. Dưới đây là một số bất lợi đó:
Người dùng không thể có địa chỉ mong muốn.
Người dùng không thể dùng nhiều cặp khóa khác nhau để tăng cường bảo mật cho tài khoản của họ.
Người dùng không thể thay đổi cặp khóa của tài khoản khi mã khóa riêng tư vô tình bị lộ, hoặc khi người dùng muốn cập nhật mã khóa riêng tư định kỳ để tăng cường bảo mật cho tài khoản.
Đây là những rào cản lớn khiến người dùng không thể coi địa chỉ là mã định danh trong nền tảng chuỗi khối. Để gỡ bỏ rào cản này, Klaytn hỗ trợ một tính năng cho phép người dùng chọn địa chỉ và cặp khóa của họ. Với tính năng này, người dùng có thể chọn địa chỉ mong muốn và họ có thể dùng nhiều cặp khóa khác nhau để tăng cường bảo mật. Số lượng cặp khóa có thể là một hoặc nhiều hơn và các cặp khóa có thể giữ các vai trò khác nhau. Để biết thêm thông tin chi tiết về nhiều cặp khóa hoặc các mã khóa theo vai trò, vui lòng tham khảo phần [Nhiều cặp khóa & khóa theo vai trò](tài khoảns.md#multiple-key-pairs-and-role-based-keys).
Bạn cũng nên lưu ý rằng Klaytn còn hỗ trợ phiên bản cũ, trong đó một cặp khóa và một địa chỉ được liên kết chặt chẽ với nhau.
Nhiều cặp khóa và khóa theo vai trò
Như đã mô tả ở trên, khi một mã khóa riêng tư bị đánh cắp, bị lộ hoặc bị xâm phạm theo cách nào đó, bạn không thể làm gì để khôi phục tính bảo mật của tài khoản: tùy chọn tốt nhất là tạo một cặp khóa khác để tạo một tài khoản mới, rồi chuyển số dư từ tài khoản cũ bị xâm nhập sang tài khoản mới đó. Việc thiếu sự hỗ trợ cho các phương án dùng khóa nâng cao, ví dụ như đa chữ ký hoặc khóa dành riêng cho từng trường hợp sử dụng lại là một sự bất tiện đáng kể khác. Để giải quyết các vấn đề đó theo cách hiệu quả hơn, tài khoản Klaytn mang đến những khả năng sau:
Tài khoản Klaytn cho phép thay đổi cặp khóa được liên kết với tài khoản.
Tài khoản Klaytn hỗ trợ nhiều cặp khóa, cùng với khả năng chỉ định từng khóa cho các mục đích khác nhau.
Tài khoản Klaytn duy trì khả năng tương thích với các tài khoản chỉ có một khóa được liên kết chặt chẽ với địa chỉ.
Bằng cách tận dụng khả năng hỗ trợ nhiều khóa theo vai trò của tài khoản Klaytn, người dùng cuối có thể xử lý tốt hơn các tình huống rủi ro về bảo mật trong thực tế, ví dụ như quản lý sai cách mã khóa riêng. Ví dụ, khi một người dùng nhận thấy mã khóa riêng tư của mình đã bị lộ, người dùng này chỉ cần thay thế mã khóa riêng tư bị lộ bằng cách xóa cặp khóa bị lộ khỏi tài khoản của mình và tạo một cặp khóa mới thay thế. Để thực hiện được điều này, chúng ta có thể dùng khóa dành riêng được dùng để cập nhật thông tin tài khoản, được tạo trước và lưu trữ riêng biệt với khóa riêng tư bị xâm phạm.
Địa chỉ mà con người đọc được (HRA)
Mặc dù mô hình địa chỉ (ví dụ: "0x0fe2e20716753082222b52e753854f40afddffd2") có điểm mạnh riêng ở chỗ mô hình này bảo vệ hiệu quả quyền riêng tư của chủ tài khoản nhưng cũng gây ra vấn đề lớn về trải nghiệm của người dùng cuối. Trước tiên, não bộ con người rất khó ghi nhớ hoặc thậm chí là nhận ra những địa chỉ như vậy, do đó, lỗi nhập địa chỉ cũng như nhiều lỗi chủ quan khác nhau rất dễ xảy ra, dẫn đến thiệt hại tài chính không nhỏ. Thứ hai, mô hình địa chỉ như vậy sẽ tước mất quyền lựa chọn cách xử lý danh tính theo cách riêng của người dùng cuối để họ có thể dễ ghi nhớ hoặc sử dụng. Kết hợp lại, những vấn đề này là một trong những rào cản khiến người dùng cuối thông thường (những người đã quen với trải nghiệm người dùng đơn giản và mượt mà hơn do các ứng dụng hoặc dịch vụ di động cũ mang đến) coi trải nghiệm người dùng dApp là xa lạ, khó hiểu và vô cùng bất tiện. Để vượt qua các thách thức như vậy mà không cần thay đổi kiến trúc ở quy mô lớn, đồng thời vẫn duy trì khả năng tương thích ngược, Klaytn đã chọn cung cấp tính năng ánh xạ giữa địa chỉ 20 byte với chuỗi văn bản có độ dài 20 byte, nhờ đó, người dùng cuối có thể chỉ định các giá trị mà họ mong muốn. Tính năng này trong Klaytn được gọi là địa chỉ mà con người đọc được (HRA). Hiện tại, tính năng này vẫn đang trong giai đoạn phát triển và chúng tôi sẽ cung cấp thêm thông tin khi tính năng này sẵn sàng cho việc sử dụng.
Định dạng khóa của ví Klaytn
Định dạng khóa của ví Klaytn được cung cấp giúp dễ dàng xử lý mã khóa riêng tư kèm theo địa chỉ tương ứng. Điều này sẽ giúp người dùng dễ dàng hơn trong việc duy trì mã khóa riêng tư của mình cùng địa chỉ. Định dạng là 0x{private key}0x{type}0x{address in hex}
ở dạng ký hiệu thập lục phân, trong đó {type}
phải là 00
. Các giá trị khác giữ nguyên. Dưới đây là ví dụ:
Định dạng này hiện được hỗ trợ trong Ví Klaytn.
Các loại tài khoản Klaytn
Có hai loại tài khoản trong Klaytn: tài khoản sở hữu bên ngoài (\EOA) và tài khoản hợp đồng thông minh (SCA).
Tài khoản sở hữu bên ngoài (EOAs)
Tài khoản sở hữu bên ngoài chứa các thông tin như số dư và số dùng một lần. Loại tài khoản này không có mã hoặc hệ thống lưu trữ. EOA được kiểm soát bằng khóa riêng tư và không có mã liên kết với chúng. EOA có thể được tạo bằng cặp khóa và nhờ đó, được kiểm soát bởi bất kỳ ai có cặp khóa đó. Khóa tài khoản được mô tả trong phần [Khóa tài khoản](tài khoảns.md#tài khoản-key).
Thuộc tính
type
uint8 (Go)
Loại tài khoản sở hữu bên ngoài. Giá trị này phải là 0x1 đối với EOA.
số dùng một lần
uint64 (Go)
Một chuỗi số dùng để xác định thứ tự giao dịch. Giao dịch cần xử lý tiếp theo sẽ có cùng số dùng một lần với giá trị này.
số dư
*big.Int (Go)
Số lượng KLAY có trong tài khoản.
humanReadable
bool (Go)
Giá trị boolean cho biết tài khoản được liên kết với một địa chỉ mà con người đọc được. Vì [HRA](tài khoảns.md#human-readable-address-hra) vẫn đang trong quá trình phát triển nên giá trị này đối với mọi tài khoản sẽ là false.
khóa
Khóa liên kết với tài khoản này. Trường này có thể là bất kỳ khóa nào trong số [AccountKeyLegacy](tài khoảns.md#tài khoảnkeylegacy), [AccountKeyPublic](tài khoảns.md#tài khoảnkeypublic), [AccountKeyFail](tài khoảns.md#tài khoảnkeyfail), [AccountKeyWeightedMultisig](tài khoảns.md#tài khoảnkeyweightedmultisig), [AccountKeyRoleBased](tài khoảns.md#tài khoảnkeyrolebased). Chữ ký trong các giao dịch được xác thực bằng khóa này.
Tài khoản hợp đồng thông minh (SCA)
Trái ngược với EOA, SCA có mã liên kết với chung và được kiểm soát bằng mã này. SCA được tạo ra bằng các giao dịch triển khai hợp đồng thông minh; khi đã được triển khai, SCA không thể tự mình khởi tạo giao dịch mới và phải được một tài khoản khác kích hoạt, tài khoản EOA hoặc SCA.
Thuộc tính
type
uint8 (Go)
Loại tài khoản hợp đồng thông minh. Giá trị này phải là 0x2 đối với SCA.
số dùng một lần
uint64 (Go)
Một chuỗi số dùng để xác định thứ tự giao dịch. Giao dịch cần xử lý tiếp theo sẽ có cùng số dùng một lần với giá trị này.
số dư
*big.Int (Go)
Số lượng KLAY có trong tài khoản.
humanReadable
bool (Go)
Giá trị boolean cho biết tài khoản được liên kết với một địa chỉ mà con người đọc được. Vì [HRA](tài khoảns.md#human-readable-address-hra) vẫn đang trong quá trình phát triển nên giá trị này đối với mọi tài khoản sẽ là false.
khóa
Khóa liên kết với tài khoản này. Trường này có thể là bất kỳ khóa nào trong số [AccountKeyLegacy](tài khoảns.md#tài khoảnkeylegacy), [AccountKeyPublic](tài khoảns.md#tài khoảnkeypublic), [AccountKeyFail](tài khoảns.md#tài khoảnkeyfail), [AccountKeyWeightedMultisig](tài khoảns.md#tài khoảnkeyweightedmultisig), [AccountKeyRoleBased](tài khoảns.md#tài khoảnkeyrolebased). Chữ ký trong các giao dịch được xác thực bằng khóa này.
codeHash
[]byte (Go)
Hàm băm của mã hợp đồng thông minh của tài khoản. Giá trị này là bất biến, nghĩa là nó chỉ được đặt khi hợp đồng thông minh được tạo.
storageRoot
[32]byte (Go)
Hàm băm 256 bit của gốc của Merkle Patricia Trie có chứa các giá trị của tất cả các biến về lưu trữ trong tài khoản.
codeFormat
uint8 (Go)
Hỗ trợ phiên bản trình thông dịch. Có thể đặt tối đa 16. Hiện tại chỉ hỗ trợ EVM(0x00).
vmVersion
uint8 (Go)
Thông tin nâng cấp giao thức (nâng cấp căn bản) vào thời điểm triển khai hợp đồng (ví dụ: 0x0(constantinople), 0x1(istanbul,london,...)). Có thể sử dụng tối đa 16. Có thể được tạo tự động cùng với hợp đồng.
LƯU Ý: Kể từ klaytn v1.7.0 trở đi, thuộc tính vmVersion sẽ được thêm vào tài khoản hợp đồng thông minh.
Mã loại tài khoản Klaytn
Dưới đây là mã loại tài khoản được chỉ định cho từng loại tài khoản.
Tài khoản sở hữu bên ngoài (EOA)
0x1
Tài khoản hợp đồng thông minh (SCA)
0x2
Khóa tài khoản
Khóa tài khoản tương ứng với cấu trúc khóa liên kết với một tài khoản.
AccountKeyNil
AccountKeyNil tương ứng với một khóa trống. Nếu một tài khoản cố sử dụng đối tượng AccountKeyNil, thì giao dịch sẽ không thành công. AccountKeyNil chỉ được dùng cho các giao dịch TxTypeAccountUpdate với các khóa theo vai trò. Ví dụ, nếu một tài khoản chỉ muốn cập nhật khóa RoleAccountUpdate, thì trường khóa của giao dịch TxTypeAccountUpdate sẽ là:
[AccountKeyNil, NewKey, AccountKeyNil]
Sau đó, chỉ có khóa RoleAccountUpdate mới được cập nhật. Các vai trò khác không được cập nhật. Tham khảo [AccountKeyBased](tài khoảns.md#tài khoảnkeyrolebased) để biết thêm thông tin.
Thuộc tính
Không có thuộc tính cho AccountKeyNil.
Mã hóa RLP
0x80
AccountKeyLegacy
AccountKeyLegacy được dùng cho tài khoản có địa chỉ được lấy từ cặp khóa tương ứng. Nếu một tài khoản có AccountKeyLegacy, quy trình xác thực giao dịch sẽ được thực hiện như dưới đây (như một nền tảng chuỗi khối điển hình đã thực hiện):
Lấy mã khóa công khai từ
ecrecover(txhash, txsig)
.Lấy địa chỉ của mã khóa công khai.
Địa chỉ là người gửi.
Thuộc tính
Type
uint8 (Go)
Loại AccountKeyLegacy. Giá trị này phải là 0x01.
Mã hóa RLP
0x01c0
AccountKeyPublic
AccountKeyPublic được dùng cho các tài khoản dùng một khóa công khai. Nếu tài khoản có một đối tượng AccountKeyPublic, thì quy trình xác thực giao dịch sẽ được thực hiện như bên dưới:
Lấy mã khóa công khai từ
ecrecover(txhash, txsig)
.Kiểm tra đảm bảo mã khóa công khai lấy được giống với khóa tương ứng
mã khóa công khai của tài khoản.
Thuộc tính
type
uint8 (Go)
Loại AccountKeyPublic. Giá trị này phải là 0x02.
Khóa
[33]byte (Go)
Khóa phải là khóa công khai được nén trên S256 curve.
Mã hóa RLP
0x02 + encode(CompressedPubKey)
LƯU Ý: CompressedPubKey là mã khóa công khai ở định dạng nén được định nghĩa trong SEC1. Tóm lại, dùng 0x02{PubkeyX} nếu PubkeyY là số chẵn, hoặc dùng 0x03{PubkeyX} trong trường hợp còn lại.
Mã hóa RLP (Ví dụ)
AccountKeyFail
Nếu tài khoản có khóa AccountKeyFail, thì quy trình xác thực giao dịch sẽ luôn thất bại. Khóa này có thể được sử dụng cho các tài khoản hợp đồng thông minh để một giao dịch được gửi từ một tài khoản hợp đồng thông minh luôn thất bại.
Thuộc tính
Loại
uint8 (Go)
Loại AccountKeyFail. Giá trị này phải là 0x03.
Mã hóa RLP
0x03c0
AccountKeyWeightedMultiSig
AccountKeyWeightedMultiSig là loại khóa tài khoản có chứa ngưỡng và WeightedPublicKeys có chứa một danh sách gồm một mã khóa công khai và trọng số của nó. Để một giao dịch được coi là hợp lệ cho một tài khoản liên kết với AccountKeyWeightedMultiSig, thì cần phải thỏa mã các điều kiện sau:
Tổng trọng số của các mã khóa công khai đã ký phải lớn hơn ngưỡng.
Giao dịch không được có chữ ký không hợp lệ.
Số lượng mã khóa công khai đã ký phải ít hơn số lượng weightedPublicKey.
LƯU Ý: Logic xác thực multiGig sau đây đã thay đổi với quá trình nâng cấp giao thức IstanbulEVM
, hay còn gọi là "nâng cấp căn bản".
Giao dịch không được có chữ ký không hợp lệ.
Số lượng mã khóa công khai đã ký phải ít hơn số lượng weightedPublicKey. Nếu bạn muốn đọc tài liệu trước đây, vui lòng tham khảo phần tài liệu trước đây.
Số khối nâng cấp giao thức IstanbulEVM
như sau.
Mạng thử nghiệm Baobab:
#75373312
Mạng chính thức Cypress:
#86816005
Thuộc tính
Loại
uint8 (Go)
Loại AccountKeyWeightedMultiSig. Giá trị này phải là 0x04.
Ngưỡng
uint (Go)
Ngưỡng xác thực. Để được coi là giao dịch hợp lệ thì tổng trọng số của các chữ ký phải lớn hơn hoặc bằng ngưỡng này.
WeightedPublicKeys
[]{uint, [33]byte} (Go)
Một danh sách khóa công khai có trọng số. Một khóa công khai có trọng số có chứa khóa công khai đã được nén và trọng số của nó.
Mã hóa RLP
0x04 + encode([threshold, [[weight, CompressedPubKey1], [weight2, CompressedPubKey2]]])
Mã hóa RLP (Ví dụ)
AccountKeyRoleBased
AccountKeyRoleBased tương ứng với một khóa theo vai trò. Các vai trò được nêu rõ trong phần [Các vai trò](tài khoảns.md#roles).
Thuộc tính
Loại
uint8 (Go)
Loại AccountKeyRoleBased. Giá trị này phải là 0x05.
Khóa
[]{AccountKey} (Go)
Một danh sách các khóa. Khóa có thể là bất kỳ khóa nào trong số AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail và AccountKeyWeightedMultiSig.
Vai trò
Các vai trò của AccountKeyRoleBased được định nghĩa bên dưới:
RoleTransaction
Chỉ mục 0. Khóa mặc định. Các giao dịch khác với TxTypeAccountUpdate cần được ký bởi khóa của vai trò này.
RoleAccountUpdate
Chỉ mục 1. Giao dịch TxTypeAccountUpdate phải được ký bởi khóa này. Nếu khóa này không hiển thị trong tài khoản, giao dịch TxTypeAccountUpdate là không hợp lệ khi dùng khóa RoleTransaction.
RoleFeePayer
Chỉ mục 2. Nếu tài khoản này muốn gửi phí tx thay cho người gửi, thì giao dịch phải được ký bởi khóa này. Nếu khóa này không hiển thị trong tài khoản, một giao dịch có phí ủy thác sẽ được xác thực bằng khóa RoleTransaction.
Mã hóa RLP
0x05 + encode([key1, key2, key3])
Lưu ý rằng key1, key2 và key3 có thể là bất kỳ khóa nào trong số các khóa trên (AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail và AccountKeyWeightedMultiSig).
Các vài trò có thể bỏ qua và có thể mở rộng
Các vai trò có thể được bỏ ra khỏi chỉ mục gần nhất và các vai trò đã bỏ qua được ánh xạ đến vai trò đầu tiên. Tuy nhiên, vai trò ở giữa thì không thể bỏ qua được, có nghĩa là không thể đặt RoleTransaction và RoleFeePayer khi không có RoleAccountUpdate. Ví dụ, nếu một khóa dựa trên vai trò được đặt là 0x05 + encode([key1, key2])
, thì RoleFeePayer sẽ có vai trò như thể khóa đó được đặt là 0x05 + encode([key1, key2, key1])
.
Tính năng này cho phép bạn thêm nhiều vai trò hơn trong tương lai. Nếu một vai trò mới được cung cấp, vai trò mới của các tài khoản đã được tạo cùng các vai trò cũ sẽ được ánh xạ đến vai trò đầu tiên.
Mã hóa RLP (Ví dụ)
Mã loại khóa tài khoản
Dưới đây là Mã loại khóa tài khoản được chỉ định cho từng Loại khóa tài khoản.
AccountKeyLegacy
0x01
AccountKeyPublic
0x02
AccountKeyFail
0x03
AccountKeyWeightedMultiSig
0x04
AccountKeyRoleBased
0x05
Last updated