Giao thức GHOST là một sự đổi mới đáng chú ý, lần đầu tiên được đề xuất bởi Yonatan Sompolinsky và Aviv Zohar vào tháng 10 năm 2013. Đây là nỗ lực nghiêm túc đầu tiên nhằm giải quyết các vấn đề liên quan đến việc sản xuất khối nhanh chóng.
Mục đích của GHOST là giải quyết vấn đề: thời gian tạo khối ngắn hơn (và do đó tốc độ xác nhận nhanh hơn) sẽ khiến nhiều khối bị "lỗi thời" hơn. sẽ giảm - vì phải mất một khoảng thời gian nhất định để các khối lan truyền trong mạng. Nếu người khai thác A khai thác một khối và phát nó ra toàn mạng và trên đường phát sóng, B cũng khai thác một khối, thì khối của B là. đã lỗi thời và việc khai thác của B không góp phần đảm bảo an ninh cho mạng.
Ngoài ra, còn có một vấn đề về tập trung hóa: nếu A là nhóm khai thác có 30% sức mạnh tính toán thì B có 10% sức mạnh tính toán. A có 70% thời gian để tạo các khối lỗi thời (vì 30% thời gian còn lại sẽ tạo khối mới nhất nên có thể coi TA lấy dữ liệu khối mới nhất “ngay lập tức” mà không cần đợi khối lan truyền), trong khi B có 90% thời gian tạo ra các khối cũ. Nếu khoảng thời gian sản xuất khối ngắn thì tỷ lệ lỗi thời sẽ cao và A sẽ giúp việc khai thác hiệu quả hơn với sức mạnh tính toán lớn hơn. Do đó, nếu các khối được tạo ra quá nhanh, các nhóm khai thác có sức mạnh tính toán mạng lớn sẽ dễ dàng độc chiếm quá trình khai thác.
Theo mô tả của Sompolinsky và Zohar, GHOST giải quyết vấn đề an ninh mạng do tạo ra các khối lỗi thời trong quá trình tính toán chuỗi nào dài nhất. vấn đề suy giảm tình dục. Nghĩa là, không chỉ khối gốc và các khối trước đó, mà cả các khối bên đã lỗi thời (trong Ethereum, chúng tôi gọi là "khối chú") cũng được thêm vào để tính toán khối nào có tổng công việc lớn nhất. Đi vào chứng minh.
Để giải quyết vấn đề thứ hai: vấn đề tập trung, chúng tôi đã áp dụng một chiến lược khác: cũng cung cấp phần thưởng khối cho các khối lỗi thời: phần thưởng cho việc khai thác các khối lỗi thời là Phần thưởng cơ bản của khối là 7/8; trong khi khối cháu chứa khối lỗi thời sẽ nhận được 1/32 phần thưởng cơ bản dưới dạng tiền thưởng. Tuy nhiên, phí giao dịch sẽ không được trao cho các khối chú và cháu.
Trong Ethereum, các khối lỗi thời chỉ có thể được đưa vào dưới dạng khối chú bởi các khối con cháu trực tiếp trong vòng 7 thế hệ của các khối anh chị em của chúng. Lý do cho hạn chế này là, trước hết, nếu giao thức GHOST không giới hạn khoảng cách giữa các thế hệ của các khối lỗi thời thì sẽ tốn rất nhiều chi phí trong việc tính toán tính hợp lệ của các khối lỗi thời. Thứ hai, chính sách khuyến khích khối lỗi thời không giới hạn sẽ; khiến thợ đào mất hứng thú khai thác trên chuỗi chính Cuối cùng, các tính toán cho thấy giới hạn chính sách phần thưởng khối lỗi thời trong lớp 7 mang lại hầu hết các tác động mong muốn mà không có tác động tiêu cực.
·
Hạn chế đối với con cháu 1 thế hệ: (Ví dụ: nếu c = con và p = cha mẹ thì c(c(c(p(p(p(head))))) không hợp lệ): Đây cũng là mục tiêu thiết kế là sự đơn giản và trình mô phỏng ở trên cho thấy điều này không gây ra rủi ro lớn về việc tập trung hóa. (Lưu ý: Câu này khó diễn giải; một ý nghĩa có thể là: hậu duệ của khối chú không thể được sử dụng làm khối chú, nghĩa là chỉ các nhánh bên thế hệ đầu tiên của chuỗi chính mới có thể được sử dụng làm khối chú.)
·
Khối chú phải hợp lệ :Khối chú phải là tiêu đề hợp lệ, không phải khối hợp lệ. Điều này cũng được thực hiện để đơn giản hóa, giữ mô hình blockchain ở dạng cấu trúc dữ liệu tuyến tính (không biến nó thành DAG). Tuy nhiên, đây cũng là một phương pháp hợp lệ để yêu cầu các khối chú phải là khối hợp lệ.
·
Phân bổ phần thưởng: 7/8 phần thưởng khai thác cơ bản được phân bổ cho khối chú và 1/32 được phân bổ cho khối cháu. Phí giao dịch cho cả hai đều là 0%. Tuy nhiên, nếu phí chiếm đa số, điều này sẽ làm mất hiệu lực cơ chế khuyến khích khối chú từ góc độ tập trung hóa; tuy nhiên, đây cũng là lý do tại sao Ethereum sẽ tiếp tục phát hành ether miễn là chúng tôi tiếp tục sử dụng PoW.
Thuật toán cập nhật độ khó
Ethereum hiện cập nhật độ khó thông qua các quy tắc sau: p> div>
Mục tiêu thiết kế của quy tắc cập nhật độ khó như sau: & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbs & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbs & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; &nbSP;
Cập nhật nhanh: Thời gian giữa các khối phải được điều chỉnh nhanh chóng khi sức mạnh băm tăng hoặc giảm;
Độ biến động thấp:Nếu công suất khai thác không đổi thì độ khó sẽ không dao động mạnh;
Đơn giản:Việc triển khai thuật toán phải tương đối đơn giản;
Bộ nhớ thấp: Thuật toán không nên dựa vào quá nhiều khối lịch sử và sử dụng càng ít "biến bộ nhớ" càng tốt. Giả sử có mười khối mới nhất, hãy thêm các biến bộ nhớ được lưu trữ trong tiêu đề của mười khối này. Các khối này có thể được sử dụng để tính toán thuật toán; style="font-weight: đậm;">Không thể phá vỡ: Thuật toán không được khuyến khích quá nhiều người khai thác giả mạo dấu thời gian hoặc nhóm khai thác để liên tục thêm hoặc xóa sức mạnh tính toán của chúng tôi. về sự biến động và khả năng chống nổ. Gần đây, chúng tôi có kế hoạch thay đổi tham số dấu thời gian để so sánh với khối cha và khối ông, vì vậy, những người khai thác sẽ chỉ có động cơ sửa đổi dấu thời gian khi khai thác 2 khối liên tiếp.
Gas và phí
Tất cả các giao dịch bằng Bitcoin gần như giống nhau, vì vậy chi phí mạng của họ được mô hình hóa trong một đơn vị duy nhất. Giao dịch trong Ethereum phức tạp hơn nên phí giao dịch cần phải tính đến nhiều khía cạnh của tài khoản, bao gồm phí băng thông mạng, phí lưu trữ và phí điện toán. Điều quan trọng nhất là ngôn ngữ lập trình Ethereum là Turing Complete, vì vậy các giao dịch sẽ sử dụng bất kỳ lượng băng thông, lưu trữ và chi phí tính toán nào và cuối cùng sẽ sử dụng bao nhiêu không thể dự đoán được một cách đáng tin cậy (vì cái gọi là "Vấn đề tạm dừng Turing"). " ) (Lưu ý: Không có cách nào đáng tin cậy để xác định liệu bất kỳ chương trình nào có thể được thực thi trên máy Turing sẽ kết thúc ở một bước hữu hạn hay không). Ngăn chặn ai đó sử dụng các vòng lặp vô hạn để thực hiện các cuộc tấn công từ chối dịch vụ là mục tiêu chính.
Cơ chế cơ bản của phí giao dịch Ethereum như sau:
Mỗi giao dịch phải cho biết sẵn sàng Lượng gas tiêu thụ (tức là chỉ định giá trị của startgas) và phí bạn sẵn sàng trả cho mỗi đơn vị gas (tức là gasprice), khi bắt đầu thực hiện giao dịch, giá trị startgas * gasprice của ether sẽ được rút khỏi tài khoản của người gửi (Lưu ý: startgas đây là gaslimit chúng ta vẫn quen dùng.)
Tất cả các thao tác trong quá trình thực hiện giao dịch, bao gồm cả việc đọc Viết đến cơ sở dữ liệu, gửi tin nhắn và mỗi bước tính toán sẽ tiêu tốn một lượng gas nhất định
Nếu giao dịch được thực hiện và lượng gas tiêu thụ ít hơn mức quy định; limit, sau đó Giao dịch được thực hiện bình thường và giá trị gas còn lại được gán cho biến gas_rem. Sau khi giao dịch hoàn tất, người gửi sẽ nhận được số Ether được trả lại có giá trị gas_rem * gasprice và phần thưởng cho người khai thác là (startgas - gas_rem). ) * giá trị gasprice của Ether;
Nếu gas được tiêu thụ trong quá trình thực hiện giao dịch, tất cả các quá trình thực thi sẽ tiếp tục như trước, nhưng giao dịch vẫn có hiệu lực, nhưng kết quả duy nhất của giao dịch là Trả tiền startgas * giá gasprice của Ether cho người khai thác, giữ nguyên mọi thứ khác;
Khi một hợp đồng gửi tin nhắn đến một hợp đồng khác, hợp đồng phụ do thông báo này gây ra có thể được Thực thi đặt giới hạn gas. Nếu quá trình thực hiện con hết xăng, quá trình thực hiện con sẽ tiếp tục như trước nhưng gas vẫn bị tiêu thụ. (Lưu ý: Tính đến thời điểm hiệu đính bài viết này (ngày 9 tháng 7 năm 2021), điều này không thay đổi nhưng có thể thay đổi trong tương lai. Xem phần "Các tính năng của EVM đáng xem xét loại bỏ")
Các điểm nêu trên phải được đáp ứng, ví dụ:
Nếu giao dịch không cần chỉ định giới hạn gas thì có hại cho người dùng sau đó gửi một giao dịch lặp qua hàng tỷ bước. Không ai có thể xử lý một giao dịch như vậy vì có thể mất nhiều thời gian để xử lý giao dịch đó; nhưng không ai có thể thông báo trước cho những người khai thác trên mạng, điều này sẽ dẫn đến lỗ hổng từ chối dịch vụ.
Một giải pháp thay thế cho việc đếm khí nghiêm ngặt là giới hạn thời gian, nhưng chúng dường như không hữu ích vì quá chủ quan (một số máy tính nhanh hơn những máy tính khác, ngay cả khi tất cả mọi người đều có cùng một máy tính, vẫn có thể có sự khác biệt).
Toàn bộ giá trị startgas * gasprice nên được đặt ngay từ đầu, để tài khoản không bị "phá sản" và không thể tiếp tục thanh toán gas trong quá trình giao dịch chi phí thực hiện. Kiểm tra số dư trong khi thực hiện cũng không có tác dụng vì tài khoản có thể chuyển số dư sang nơi khác.
Nếu việc thực hiện giao dịch không được khôi phục hoàn toàn (được khôi phục) khi không đủ gas, hợp đồng phải áp dụng các biện pháp bảo mật mạnh mẽ để ngăn hợp đồng thay đổi. .
Nếu hạn chế phụ không tồn tại, các tài khoản độc hại có thể thực hiện các cuộc tấn công từ chối dịch vụ đối với các hợp đồng khác. Trước tiên, kẻ tấn công có thể đạt được thỏa thuận với hợp đồng nạn nhân, sau đó chèn một vòng lặp vô hạn vào đầu quá trình tính toán. Sau đó gửi tin nhắn đến hợp đồng nạn nhân hoặc bất kỳ nỗ lực khắc phục nào của hợp đồng nạn nhân sẽ làm bế tắc toàn bộ giao dịch. (Lưu ý: Câu này cũng khó hiểu.)
Yêu cầu người gửi giao dịch thanh toán gas thay vì hợp đồng, điều này làm tăng đáng kể khả năng hoạt động của các nhà phát triển. Các phiên bản đầu tiên của Ethereum sử dụng hợp đồng để trả tiền gas, dẫn đến một vấn đề khá nghiêm trọng: mỗi hợp đồng phải triển khai mã "người gác cổng" để đảm bảo rằng mỗi tin nhắn đến đều cung cấp cho hợp đồng đủ Ethereum để tiêu thụ.
Tính toán lượng gas tiêu thụ có đặc điểm sau:
Đối với bất kỳ giao dịch nào, phí cơ bản là 21.000 gas sẽ được tính. Các khoản phí này bao gồm chi phí chạy thuật toán đường cong elip, được thiết kế để khôi phục địa chỉ của người gửi từ chữ ký, cũng như dung lượng ổ cứng và băng thông dành để lưu trữ các giao dịch.
Giao dịch có thể bao gồm lượng "dữ liệu" không giới hạn. Một số mã hoạt động nhất định trong máy ảo cho phép các hợp đồng nhận các giao dịch đó truy cập vào dữ liệu này. Quy tắc "mức tiêu thụ cố định" đối với dữ liệu là: 4 gas cho mỗi byte 0 và 68 gas cho các byte khác 0. Công thức này phát sinh do hầu hết dữ liệu giao dịch được người dùng gửi đến hợp đồng bao gồm một chuỗi các tham số 32 byte, hầu hết trong số đó có nhiều byte 0 ở đầu. Cấu trúc này có vẻ không hiệu quả nhưng do có thuật toán nén nên nó thực sự rất hiệu quả. Chúng tôi hy vọng rằng cấu trúc này sẽ thay thế các cơ chế khác phức tạp hơn bao bọc chặt chẽ các đối số dựa trên số byte dự kiến, dẫn đến độ phức tạp đáng kể của giai đoạn biên dịch. Đây là một ngoại lệ đối với mô hình phức tạp sandwich, nhưng nó cũng là một mô hình hợp lý do tỷ lệ chi phí-lợi ích.
Chi phí của mã hoạt động SSTORE được sử dụng để đặt mục lưu trữ tài khoản là: 1) Khi thay đổi giá trị 0 thành giá trị khác 0, 20.000 gas là 2) Thay đổi giá trị 0 thành giá trị 0 hoặc giá trị khác 0 thành giá trị khác 0, tiêu tốn 5000 gas; 3) Thay đổi giá trị khác 0 thành giá trị 0 cũng tiêu tốn 5000 gas; giao dịch được thực hiện thành công (tức là giao dịch hoàn thành mà không hết gas)) sẽ hoàn lại 15.000 gas. Số tiền hoàn trả tối đa là 50% tổng lượng gas tiêu thụ của giao dịch. Điều này mang lại cho mọi người một động lực nhỏ để dọn sạch các vật phẩm trong kho. Chúng tôi nhận thấy do thiếu các ưu đãi như vậy nên không gian lưu trữ của nhiều hợp đồng không được sử dụng hiệu quả, dẫn đến dữ liệu lưu trữ mở rộng nhanh chóng. Thiết kế này mang lại hầu hết lợi ích của mô hình “thu tiền thuê kho liên tục” mà không làm mất đi sự đảm bảo rằng hợp đồng sẽ tồn tại mãi mãi sau khi được xác lập. Cơ chế hoàn trả chậm trễ là cần thiết vì nó có thể ngăn chặn các cuộc tấn công từ chối dịch vụ: kẻ tấn công có thể gửi một giao dịch chứa một lượng nhỏ gas và lặp qua một số lượng lớn các vật phẩm lưu trữ cho đến khi sử dụng hết gas, việc này tiêu tốn rất nhiều điện toán xác minh quyền lực, nhưng trên thực tế, kho lưu trữ không thực sự được dọn sạch và không cần nhiều gas. Giới hạn 50% là để đảm bảo rằng những người khai thác đóng gói giao dịch vẫn có thể xác định giới hạn trên về thời gian tính toán để thực hiện giao dịch.
(Lưu ý: Thứ nhất, mức tiêu thụ gas của các opcode truy cập trạng thái như SSTORE đã thay đổi nhiều lần với hard fork của Ethereum. Kể từ tháng 7 năm 2021 Vào tháng 9, giá trị mới nhất có thể được tìm thấy trong "Tổng quan về nội dung nâng cấp Berlin"; trong tương lai gần, giá trị của opcode này sẽ tiếp tục thay đổi, thứ hai, cơ chế hoàn trả gas ở đây đã được chứng minh là không bắt đầu giảm bớt vấn đề mở rộng của nhà nước; dữ liệu, nhưng thay vào đó, Vấn đề này càng trở nên trầm trọng hơn vì mọi người có thể viết rất nhiều dữ liệu rác khi giá gas thấp và xóa dữ liệu này để lấy gas khi giá gas cao. Đây là nguyên tắc của "GasToken", hiện tại. được xác định tại "London". Cơ chế hoàn trả gas sẽ được thay đổi trong đợt fork, xem "Bản xem trước nâng cấp Ethereum" London")
Dữ liệu thông báo được cung cấp bởi hợp đồng không có chi phí. Vì không có dữ liệu nào thực sự được sao chép trong cuộc gọi tin nhắn nên dữ liệu cuộc gọi có thể được xem đơn giản như một con trỏ tới bộ nhớ của hợp đồng cha, không thay đổi trong khi tiến trình con đang thực thi.
Bộ nhớ là một mảng có thể mở rộng vô hạn. Tuy nhiên, mỗi lần mở rộng 32 byte bộ nhớ sẽ tốn 1 gas. sẽ là 32 từ Tiết kiệm tiền. (Lưu ý: bộ nhớ thường được dịch là bộ nhớ, nhưng trong ngữ cảnh của Ethereum, nó là một trong ba loại EVM lưu trữ dữ liệu nên nó không được dịch để thể hiện tính đặc thù của nó.)
Thời gian tính toán của một số opcode phụ thuộc rất nhiều vào các tham số và việc tính toán chi phí gas thay đổi linh hoạt. Ví dụ: chi phí EXP theo cấp số nhân (10 gas + 10 gas/byte, nghĩa là x^0 = 1 gas, x^1 ... x^255 = 2 gas, x^256 ... x^65535 = 3 khí, v.v.). Chi phí sao chép opcode (ví dụ: CALLDATACOPY, CODECOPY, EXTCODECOPY) là 1 gas + 1 gas/32 byte (làm tròn; quy tắc tương tự cho opcode LOG). Chi phí mở rộng bộ nhớ không được bao gồm ở đây. Nếu được đưa vào, nó sẽ trở thành một vectơ tấn công bình phương (50.000 CALLDATACOPY, tiêu thụ 50.000 gas mỗi lần, vì vậy số tiền tính toán sẽ là 50.000^2, nhưng nếu không sử dụng quy tắc tính phí động, bạn chỉ cần trả ~50.000 gas).
Opcode CALL (và CALLCODE) tốn thêm 9000 gas nếu giá trị khác 0. Điều này là do bất kỳ hoạt động chuyển giá trị nào cũng sẽ khiến dung lượng lưu trữ lịch sử của nút lưu trữ tăng lên đáng kể. Xin lưu ý rằng mức tiêu thụ thực tế của hoạt động là 6700; tuy nhiên, dựa trên điều này, chúng tôi buộc một giá trị gas được tự động cung cấp cho người nhận, ít nhất là 2300. Điều này được thực hiện để ví chấp nhận giao dịch có ít nhất đủ gas để tạo nhật ký. (Lưu ý: Xem phần "Các tính năng EVM đáng xem xét loại bỏ")
Một phần quan trọng khác của cơ chế Gas là các nguyên tắc kinh tế được phản ánh trong chính giá gas. Trong Bitcoin, cách tiếp cận mặc định là áp dụng cách tiếp cận phí hoàn toàn tự nguyện, trong đó các thợ mỏ đóng vai trò là người gác cổng và tự động thiết lập mức phí tối thiểu. Ethereum cho phép người gửi giao dịch đặt bất kỳ lượng gas nào. Phương pháp này rất phổ biến trong cộng đồng Bitcoin vì nó là biểu hiện của “nền kinh tế thị trường”: cho phép các thợ mỏ và nhà giao dịch xác định giá dựa trên cung và cầu. Tuy nhiên, vấn đề với cách tiếp cận này là việc xử lý giao dịch không tuân theo các nguyên tắc thị trường. Mặc dù việc xử lý giao dịch có thể được coi là một dịch vụ do người khai thác cung cấp cho người gửi (nghe có vẻ trực quan), nhưng trên thực tế, mọi giao dịch do người khai thác xử lý phải được xử lý bởi mọi nút trong mạng, do đó, phần lớn chi phí xử lý giao dịch sẽ do bên thứ ba, chứ không phải người khai thác quyết định có xử lý nó hay không. Vì vậy, vấn đề “bi kịch của chung” rất dễ xảy ra.
Hiện tại, do thiếu thông tin rõ ràng về cách hoạt động của thợ mỏ trong thực tế, chúng tôi sẽ áp dụng một phương pháp rất đơn giản và công bằng: một hệ thống bỏ phiếu để thiết lập các khu vực riêng lẻ Tổng lượng gas mà khối có thể tiêu thụ. Người khai thác có quyền thay đổi giới hạn gas của khối mới nhất thêm 0,0975% (1/1024) làm giới hạn gas của khối hiện tại. Vì vậy, giới hạn gas cuối cùng phải là giá trị trung bình do thợ mỏ đặt ra. Chúng tôi hy vọng sẽ áp dụng phương pháp phân nhánh mềm trong tương lai để sử dụng các thuật toán chính xác hơn.
Máy ảo
Máy ảo Ethereum là công cụ thực thi mã giao dịch và là điểm khác biệt cốt lõi giữa Ethereum và các hệ thống khác. Xin lưu ý rằng máy ảo phải được xem xét riêng biệt với "mô hình hợp đồng và tin nhắn". Ví dụ: opcode SIGNEXTEND là một chức năng của máy ảo, nhưng trên thực tế "một hợp đồng có thể gọi các hợp đồng khác và chỉ định giá trị giới hạn gas của cuộc gọi phụ" là một phần của "mô hình hợp đồng và tin nhắn".
Mục tiêu thiết kế của EVM như sau:
Đơn giản:Mã hoạt động nên càng ít và ở mức độ thấp càng tốt; loại dữ liệu nên càng ít càng tốt; cấu trúc máy ảo nên càng ít càng tốt;
Kết quả rõ ràng:Không có chỗ cho sự mơ hồ trong đặc tả VM và kết quả phải hoàn toàn chắc chắn. Ngoài ra, các bước tính toán phải chính xác để có thể đo được lượng khí tiêu thụ
Tiết kiệm không gian: Các thành phần EVM phải nhỏ gọn nhất có thể;
Chuyên dùng cho mục đích sử dụng: span> span> Các ứng dụng được xây dựng trên VM phải có khả năng xử lý các địa chỉ 20 byte và giá trị mã hóa tùy chỉnh 32 bit, đồng thời có khả năng thực hiện các hoạt động mô-đun để mã hóa tùy chỉnh, đọc khối và tương tác với dữ liệu và trạng thái giao dịch; /div>
Đơn giản và an toàn: Để VM không bị khai thác, cần phải dễ tạo Một tập hợp các thao tác trên mô hình chi phí tiêu thụ gas;
Thân thiện với việc tối ưu hóa: phải dễ tối ưu hóa, để có thể xây dựng các phiên bản biên dịch đúng lúc (JIT) và tăng tốc của VM.
Đồng thời, EVM còn có thiết kế đặc biệt sau:
Sự khác biệt giữa lưu trữ tạm thời/vĩnh viễn:
h4>
Trước tiên chúng ta hãy xem lưu trữ tạm thời và lưu trữ vĩnh viễn là gì . Bộ nhớ tạm thời: tồn tại trong mỗi phiên bản của VM và biến mất sau khi quá trình thực thi VM kết thúc. Lưu trữ vĩnh viễn: tồn tại trong lớp trạng thái blockchain. Giả sử cây sau được thực thi (S đại diện cho bộ nhớ vĩnh viễn, M đại diện cho bộ nhớ tạm thời):
A gọi B;
B sets B.S[0]=5, B.M[0 ] =9 ;
B gọi C;
C gọi B.
Lúc này, nếu B cố đọc B.S[0] , nó sẽ nhận được dữ liệu được lưu trữ trước B, tức là 5; B cố đọc B.M[0] , nó sẽ nhận được 0 vì B.M là bộ lưu trữ tạm thời và nó là một phiên bản mới của máy ảo khi nó được đọc. Trong cuộc gọi bên trong, nếu B.M[0] = 13 và B.S[0] = 17 thì cả cuộc gọi bên trong và cuộc gọi đến C đều chấm dứt và quay trở lại cuộc gọi bên ngoài của B (cuộc gọi bên ngoài), khi bạn đọc M, bạn sẽ thấy B.M[0] = 9 (giá trị này được đặt trong phiên bản thực thi cuối cùng của cùng một VM), B.S[0] = 17 . Nếu cuộc gọi ra bên ngoài của B kết thúc và A gọi lại cho B thì ta sẽ thấy B.M[0] = 0 và B.S[0] = 17. Mục đích của sự khác biệt này là: 1. Mỗi phiên bản thực thi được phân bổ không gian bộ nhớ sẽ không bị hạn chế bởi các lệnh gọi vòng lặp, điều này giúp việc lập trình an toàn trở nên dễ dàng hơn. 2. Cung cấp dạng bộ nhớ có thể hoạt động nhanh chóng: vì cây cần được sửa đổi nên việc cập nhật bộ nhớ phải chậm.
Chế độ ngăn xếp/bộ nhớ: Ban đầu, có ba trạng thái tính toán (ngoại trừ bộ đếm chương trình trỏ tới lệnh tiếp theo) Các loại: ngăn xếp (ngăn xếp, ngăn xếp LIFO tiêu chuẩn 32 byte), bộ nhớ (bộ nhớ, mảng byte tạm thời có thể được mở rộng vô thời hạn), bộ lưu trữ (bộ nhớ vĩnh viễn). Về mặt lưu trữ tạm thời, các lựa chọn thay thế cho ngăn xếp và bộ nhớ là mô hình chỉ có bộ nhớ hoặc kết hợp giữa các thanh ghi và bộ nhớ (không có nhiều khác biệt giữa hai loại này, các thanh ghi về cơ bản cũng là một loại bộ nhớ). Trong trường hợp này, mỗi lệnh có ba tham số, ví dụ: ADD R1 R2 R3: M[R1] = M[R2] + M[R3]. Lý do chọn mô hình ngăn xếp là hiển nhiên, nó làm cho mã nhỏ hơn gấp 4 lần.
Kích thước từ 32 byte: Trong hầu hết các cấu trúc, Giống như Bitcoin, kích thước từ là 4 hoặc 8 byte. 4 hoặc 8 byte là quá giới hạn đối với địa chỉ lưu trữ và tính toán mật mã. Nếu không có hạn chế về kích thước thì rất khó để thiết lập một mô hình khí an toàn tương ứng. 32 byte là kích thước lý tưởng vì nó đủ lớn để lưu trữ các giá trị và địa chỉ lớn được yêu cầu bởi nhiều thuật toán mã hóa mà không quá lớn đến mức kém hiệu quả.
Chúng tôi có máy ảo riêng: Máy ảo của chúng tôi sử dụng java, Lisp và Ngôn ngữ phát triển như Lua. Chúng tôi tin rằng việc phát triển một máy ảo chuyên nghiệp là đáng giá vì: 1) Đặc tả máy ảo của chúng tôi đơn giản hơn nhiều so với nhiều máy ảo khác, vì các máy ảo khác trả ít hơn cho độ phức tạp, điều đó có nghĩa là chúng dễ dàng thay đổi hơn, tuy nhiên, mỗi bit bổ sung đều phải phức tạp hơn; độ phức tạp được thêm vào giải pháp của chúng tôi sẽ gây trở ngại cho việc phát triển chuyên sâu và mang lại các lỗi bảo mật tiềm ẩn, chẳng hạn như lỗi đồng thuận, khiến chi phí phức tạp của chúng tôi rất cao; 2) VM của chúng tôi chuyên biệt hơn, chẳng hạn như hỗ trợ 32 byte; có các phần phụ thuộc bên ngoài phức tạp, điều này sẽ khiến quá trình cài đặt của chúng tôi không thành công; 4) Một cơ chế xem xét hoàn chỉnh có thể dành riêng cho các yêu cầu bảo mật đặc biệt; Ngay cả việc sử dụng máy ảo bên ngoài cũng không tiết kiệm được nhiều công việc.
Sử dụng kích thước bộ nhớ có thể thay đổi, có thể mở rộng:Kích thước bộ nhớ cố định là Những hạn chế không cần thiết, quá nhỏ hoặc quá lớn đều không phù hợp. Nếu kích thước bộ nhớ cố định, mỗi khi truy cập vào bộ nhớ, bạn cần kiểm tra xem quyền truy cập có vượt quá giới hạn hay không. Rõ ràng, điều này không hiệu quả. 1024 Giới hạn độ sâu cuộc gọi: Nhiều ngôn ngữ lập trình gặp sự cố do độ sâu cuộc gọi quá sâu trước khi tràn bộ nhớ. Vì vậy, chỉ sử dụng giới hạn gas khối làm giới hạn là không đủ.
Không có loại: Chỉ để cho ngắn gọn. Tuy nhiên, DIV, SDIV, MOD, SMOD sẽ sử dụng các opcode có dấu hoặc không dấu (hóa ra đối với các opcode ADD và MUL, có dấu và không dấu là tương đương nhau); ở độ dài 32 bit, a * b -> (a * b) / 2^32, a / b -> a * 2^32 / b , +, - và * Bất biến đối với số nguyên.
Lưu ý: Có đoạn sau trong bản dịch gốc, nhưng đoạn tương ứng của nó đã bị xóa trong phiên bản hiện tại của văn bản gốc: Không có giới hạn kích thước ngăn xếp: không có lý do gì đặc biệt! Trong nhiều trường hợp, thiết kế này không thực sự cần thiết; vì nắp gas trên và khối gas sẽ luôn đóng vai trò là mức trần cho việc tiêu thụ từng nguồn tài nguyên.
Chức năng và ý định của một số opcode trong VM này rất dễ hiểu, nhưng một số opcode thì không dễ hiểu Sau đây là một số lý do đặc biệt:
ADDMOD, MULMOD:Trong hầu hết các trường hợp, mulmod(a, b, c ) = a * b % c , nhưng trong thuật toán đường cong elip, thao tác mô-đun 32 byte được sử dụng và thực thi trực tiếp a * b % c thực tế là đang thực thi ((a * b) % 2^256) % c , bạn sẽ nhận được kết quả hoàn toàn khác. Rất khó khăn và tẻ nhạt khi thực hiện phép tính đồng thuận a * b % c cho giá trị 32 byte trong không gian 32 byte.
SIGNEXTEND:Chức năng của opcode SIGNEXTEND là tạo điều kiện thuận lợi cho việc lựa chọn các chữ ký lớn số nguyên Chuyển đổi kiểu thành số nguyên có dấu nhỏ. Số nguyên có dấu nhỏ rất hữu ích vì các máy ảo JIT trong tương lai có thể phát hiện các khối mã chạy dài chủ yếu xử lý số nguyên 32 byte và số nguyên có dấu nhỏ có thể tăng tốc độ xử lý.
SHA3: Trong mã Ethereum, SHA3 đóng vai trò là một mã an toàn, có độ bền cao, phương pháp ánh xạ băm dữ liệu có độ dài thay đổi, được sử dụng rộng rãi. Thông thường, các hàm Hash được sử dụng để ngăn chặn các va chạm độc hại khi sử dụng bộ nhớ và cũng được sử dụng khi xác thực cây Merkle và các cấu trúc dữ liệu Ethereum tương tự. Điều quan trọng là các hàm băm tương tự như SHA3, chẳng hạn như SHA256, ECRECVOR, RIPEM160, không được đưa vào dưới dạng opcode mà dưới dạng hợp đồng giả. Mục đích của việc này là đặt chúng vào một danh mục riêng để nếu và khi chúng tôi nghĩ ra một hệ thống "plugin gốc" thích hợp trong tương lai, thì có thể thêm nhiều hợp đồng như vậy hơn mà không cần phải mở rộng opcode.
ORIGIN: Opcode ORIGIN được cung cấp bởi người gửi giao dịch. Chức năng chính của nó là cho phép. hợp đồng trả lại tiền gas.
COINBASE: Các chức năng chính của COINBASE là: 1) Cho phép mạng tiền tệ phụ security Đóng góp; 2) Cho phép người khai thác thiết lập các ứng dụng dựa trên sự đồng thuận phụ, chẳng hạn như Schellingcoin, như một nền kinh tế phi tập trung.
PREVHASH:PREVHASH có thể được sử dụng như một nguồn ngẫu nhiên bán an toàn. Ngoài ra, hợp đồng được phép đánh giá bằng chứng trạng thái cây Merkle của khối trước đó mà không cần cấu trúc đệ quy "Ethereum light client" rất phức tạp.
EXTCODESIZE, EXTCODECOPY:Chức năng chính là để hợp đồng kiểm tra các hợp đồng khác dựa trên trên mã mẫu, thậm chí mô phỏng các hợp đồng khác trước khi tương tác với chúng. Xem
JUMPDEST: Khi đích nhảy bị giới hạn ở một vài chỉ mục (đặc biệt, độ phức tạp tính toán của các bước nhảy đích động là O(log(thử thách hiệu quả Số lượng đích) ), trong khi các bước nhảy tĩnh luôn không đổi), thì việc triển khai máy ảo JIT đơn giản hơn. Do đó, chúng ta cần: 1) hạn chế các đích nhảy có thể thay đổi hiệu quả; 2) khuyến khích sử dụng các bước nhảy tĩnh thay vì động. Để đạt được hai mục tiêu này, chúng tôi đặt ra các quy tắc sau: 1) lần nhảy ngay sau lần đẩy có thể nhảy đến bất kỳ đâu, không chỉ một lần nhảy khác; 2) các lần nhảy khác chỉ có thể nhảy tới JUMPDEST. Cần hạn chế các bước nhảy để bạn có thể xác định xem bước nhảy hiện tại là bước nhảy tĩnh hay động bằng cách xem thao tác trước đó trong mã. Việc không cần phải nhảy tĩnh là động lực thúc đẩy việc sử dụng chúng. Việc tắt tính năng nhảy vào dữ liệu đẩy cũng sẽ tăng tốc độ biên dịch và thực thi máy ảo JIT.
LOG:LOG là nhật ký các sự kiện.
CALLCODE: Mã opcode này cho phép hợp đồng sử dụng mục lưu trữ của chính nó, trong một riêng biệt Các "chức năng" của các hợp đồng khác được gọi trong không gian ngăn xếp và bộ nhớ. Điều này cho phép triển khai linh hoạt mã thư viện tiêu chuẩn trên blockchain.
SELFDESTRUCT: Cho phép hợp đồng tự xóa nếu nó không còn cần thiết tồn tại . SELFDESTRUCT không được thực thi ngay lập tức mà sau khi giao dịch được thực hiện. Điều này là do nếu SELFDESTRUCT được phép khôi phục sau khi thực thi, nó sẽ làm tăng đáng kể độ phức tạp của bộ đệm và không có lợi cho việc triển khai VM hiệu quả.
PC: Mặc dù về mặt lý thuyết, các opcode của PC không cần thiết vì tất cả các opcode của PC Các phiên bản của thay vào đó, tất cả đều được triển khai bằng cách thêm chỉ mục của thao tác đẩy vào bộ đếm chương trình thực tế, nhưng việc sử dụng PC cho phép tạo các vị trí mã độc lập (các hàm được biên dịch có thể được sao chép và dán vào các hợp đồng khác và sẽ không bị gián đoạn nếu chúng kết thúc tại một chỉ số khác nhau) ).
Chào mừng bạn tham gia cộng đồng chính thức của BlockBeats:
Nhóm Telegram đăng ký: https://t.me/theblockbeats
Nhóm Telegram thảo luận: https://t.me/BlockBeats_App
Tài khoản Twitter chính thức: https://twitter.com/BlockBeatsAsia