Cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai: sử dụng CREATE2 để trao đổi tiền điện tử

Chủ đề về blockchain không chỉ là nguồn gốc của mọi kiểu cường điệu mà còn là nguồn gốc của những ý tưởng rất có giá trị từ quan điểm công nghệ. Vì vậy, cô không qua mặt được cư dân của thành phố đầy nắng. Mọi người đang quan sát kỹ, nghiên cứu, cố gắng chuyển chuyên môn của họ về cơ sở thông tin truyền thống sang hệ thống blockchain. Cho đến nay, theo quan điểm: một trong những bước phát triển của Rostelecom-Solar là có thể kiểm tra tính bảo mật của phần mềm dựa trên blockchain. Và trong quá trình đó, một số suy nghĩ nảy sinh về việc giải quyết các vấn đề ứng dụng của cộng đồng blockchain. Một trong những mẹo vặt cuộc sống này - cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai bằng CREATE2 - hôm nay tôi muốn chia sẻ với bạn phần tóm tắt.

Cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai: sử dụng CREATE2 để trao đổi tiền điện tử
Opcode CREATE2 đã được thêm vào hard fork Constantinople vào ngày 28 tháng XNUMX năm nay. Như đã nêu trong EIP, opcode này được giới thiệu chủ yếu cho các kênh trạng thái. Tuy nhiên, chúng tôi đã sử dụng nó để giải quyết một vấn đề khác.

Có người dùng có số dư trên sàn giao dịch. Chúng tôi phải cung cấp cho mỗi người dùng một địa chỉ Ethereum để bất kỳ ai cũng có thể gửi mã thông báo đến đó, từ đó bổ sung tài khoản của họ. Hãy gọi những địa chỉ này là "ví". Khi mã thông báo đến ví, chúng tôi phải gửi chúng đến một ví duy nhất (ví nóng).

Trong các phần sau, tôi phân tích các tùy chọn để giải quyết vấn đề này mà không cần CREATE2 và giải thích lý do tại sao chúng tôi từ bỏ chúng. Nếu bạn chỉ quan tâm đến kết quả cuối cùng, bạn có thể tìm thấy nó trong phần Giải pháp cuối cùng.

Địa chỉ Ethereum

Giải pháp đơn giản nhất là tạo địa chỉ ethereum mới cho người dùng mới. Những địa chỉ này sẽ là ví. Để chuyển token từ ví sang ví nóng, bạn cần ký giao dịch bằng cách gọi hàm chuyển khoản() bằng khóa riêng của ví từ phần phụ trợ.

Cách tiếp cận này có những ưu điểm sau:

  • nó đơn giản
  • chi phí chuyển mã thông báo từ ví sang ví nóng bằng với chi phí gọi hàm chuyển khoản()

Tuy nhiên, chúng tôi đã từ bỏ phương pháp này vì nó có một nhược điểm đáng kể: bạn cần lưu trữ khóa riêng ở đâu đó. Và không chỉ chúng có thể bị mất mà bạn còn cần quản lý cẩn thận quyền truy cập vào các khóa này. Nếu ít nhất một trong số chúng bị xâm phạm thì token của một người dùng nhất định sẽ không đến được ví nóng.

Cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai: sử dụng CREATE2 để trao đổi tiền điện tử

Tạo hợp đồng thông minh riêng cho từng người dùng

Việc triển khai hợp đồng thông minh riêng cho từng người dùng cho phép bạn không lưu trữ khóa riêng tư từ ví trên máy chủ. Sàn giao dịch sẽ gọi hợp đồng thông minh này để chuyển token sang ví nóng.

Chúng tôi cũng đã từ bỏ giải pháp này vì người dùng không thể hiển thị địa chỉ ví của mình nếu không triển khai hợp đồng thông minh (điều này thực sự có thể thực hiện được, nhưng theo một cách khá phức tạp với những nhược điểm khác mà chúng tôi sẽ không thảo luận ở đây). Trên sàn giao dịch, người dùng có thể tạo bao nhiêu tài khoản tùy thích và mọi người đều cần có ví riêng của mình. Điều này có nghĩa là chúng ta cần bỏ tiền ra để triển khai hợp đồng mà không hề chắc chắn rằng người dùng sẽ sử dụng tài khoản này.

Mã lệnh TẠO2

Để khắc phục sự cố của phương pháp trước, chúng tôi quyết định sử dụng opcode CREATE2. CREATE2 cho phép bạn xác định trước địa chỉ nơi hợp đồng thông minh sẽ được triển khai. Địa chỉ được tính bằng công thức sau:

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


Ở đâu:

  • địa chỉ — địa chỉ của hợp đồng thông minh sẽ gọi CREATE2
  • muối - giá trị ngẫu nhiên
  • init_code - mã byte hợp đồng thông minh để triển khai

Điều này đảm bảo rằng địa chỉ chúng tôi cung cấp cho người dùng sẽ thực sự chứa mã byte mong muốn. Ngoài ra, hợp đồng thông minh này có thể được triển khai bất cứ khi nào chúng ta cần. Ví dụ: khi người dùng quyết định sử dụng ví của họ lần đầu tiên.
Cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai: sử dụng CREATE2 để trao đổi tiền điện tử
Hơn nữa, bạn có thể tính toán địa chỉ hợp đồng thông minh mỗi lần thay vì lưu trữ nó, bởi vì:

  • địa chỉ trong công thức là không đổi vì đó là địa chỉ nhà máy sản xuất ví của chúng tôi
  • muối - hàm băm user_id
  • init_code là vĩnh viễn vì chúng tôi sử dụng cùng một ví

Nhiều cải tiến hơn

Giải pháp trước đây vẫn còn một nhược điểm: bạn cần trả tiền cho việc triển khai hợp đồng thông minh. Tuy nhiên, bạn có thể thoát khỏi nó. Đối với điều này bạn có thể gọi hàm chuyển khoản(), đó là tự hủy() trong hàm tạo ví. Và sau đó gas để triển khai hợp đồng thông minh sẽ được trả lại.

Trái với suy nghĩ của nhiều người, bạn có thể triển khai hợp đồng thông minh đến cùng một địa chỉ nhiều lần với opcode CREATE2. Điều này là do CREATE2 kiểm tra xem nonce của địa chỉ đích có bằng 1 hay không (nó được gán giá trị "XNUMX" ở đầu hàm tạo). Đồng thời, chức năng tự hủy() đặt lại địa chỉ nonce mỗi lần. Do đó, nếu bạn gọi lại CREATE2 với cùng các đối số, kiểm tra nonce sẽ vượt qua.

Xin lưu ý rằng giải pháp này tương tự như giải pháp địa chỉ ethereum nhưng không cần lưu trữ khóa riêng. Chi phí chuyển tiền từ ví sang ví nóng xấp xỉ bằng chi phí gọi một hàm chuyển khoản(), vì chúng tôi không trả tiền cho việc triển khai hợp đồng thông minh.

Quyết định cuối cùng

Cách xác định địa chỉ của hợp đồng thông minh trước khi triển khai: sử dụng CREATE2 để trao đổi tiền điện tử

Chuẩn bị ban đầu:

  • chức năng lấy muối bằng cách user_id
  • hợp đồng thông minh sẽ gọi opcode CREATE2 với muối thích hợp (tức là nhà máy ví)
  • mã byte của ví tương ứng với hợp đồng với hàm tạo sau:

constructor () {
    address hotWallet = 0x…;
    address token = 0x…;
    token.transfer (hotWallet, token.balanceOf (address (this)));
    selfdestruct (address (0));
}


Đối với mỗi người dùng mới, chúng tôi hiển thị địa chỉ ví của họ bằng cách tính toán

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


Khi người dùng chuyển mã thông báo đến địa chỉ ví tương ứng, chương trình phụ trợ của chúng tôi sẽ thấy sự kiện Chuyển với tham số _tobằng với địa chỉ ví. Tại thời điểm này, số dư của người dùng trên sàn giao dịch đã có thể tăng trước khi triển khai ví.

Khi đủ số token tích lũy trong địa chỉ ví, chúng tôi có thể chuyển tất cả chúng cùng một lúc sang ví nóng. Để thực hiện việc này, phần phụ trợ gọi hàm nhà máy hợp đồng thông minh, hàm này thực hiện các hành động sau:

function deployWallet (соль uint256) {
    bytes memory walletBytecode =…;
    // invoke CREATE2 with wallet bytecode and salt
}


Do đó, trình tạo hợp đồng thông minh của ví được gọi, nó sẽ chuyển tất cả các mã thông báo của nó đến địa chỉ ví nóng và sau đó tự hủy.

Mã hoàn chỉnh có thể được tìm thấy đây. Xin lưu ý rằng đây không phải là mã sản xuất của chúng tôi vì chúng tôi đã quyết định tối ưu hóa mã byte của ví và viết nó thành mã opcode.

Tác giả Pavel Kondratenkov, chuyên gia Ethereum

Nguồn: www.habr.com

Thêm một lời nhận xét