Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ систСмы Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с нуля. Π§Π°ΡΡ‚ΡŒ 1: символьная Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина Π½Π° PHP ΠΈ Python

Π€ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Π°Ρ вСрификация β€” это ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π»ΠΈΠ±ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Ρ€ΡƒΠ³ΠΎΠΉ.

Π­Ρ‚ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· самых ΠΌΠΎΡ‰Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π½Π°ΠΉΡ‚ΠΈ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ всС уязвимости Π»ΠΈΠ±ΠΎ ΠΆΠ΅ Π΄ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΡ… Π½Π΅Ρ‚.

Π‘ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΎ Π’ΠΎΠ»ΠΊΠ΅, КозС, ΠΈ капустС Π² ΠΌΠΎΠ΅ΠΉ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅.

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ я ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠΆΡƒ ΠΎΡ‚ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π·Π°Π΄Π°Ρ‡, ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌ, ΠΈ ΠΎΠΏΠΈΡˆΡƒ,
ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… Π² систСмы Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€Π°Π²ΠΈΠ» автоматичСски.

Для этого я написал свой Π°Π½Π°Π»ΠΎΠ³ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΌΠ°ΡˆΠΈΠ½Ρ‹, Π½Π° ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Ρ….

Она Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ транслируСт Π΅Π³ΠΎ Π² систСму ΡƒΡ€Π°Π²Π½Π΅Π½ΠΈΠΉ (SMT), ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ способом.

Π’Π°ΠΊ ΠΊΠ°ΠΊ информация ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… вычислСниях прСдставлСна Π² ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅ довольно ΠΎΠ±Ρ€Ρ‹Π²ΠΎΡ‡Π½ΠΎ,
я Π²ΠΊΡ€Π°Ρ‚Ρ†Π΅ ΠΎΠΏΠΈΡˆΡƒ Ρ‡Ρ‚ΠΎ это Ρ‚Π°ΠΊΠΎΠ΅.

Π‘ΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ вычислСния ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой способ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° ΡˆΠΈΡ€ΠΎΠΊΠΎΠΌ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π³Π»Π°Π²Π½Ρ‹ΠΌ инструмСнтом для Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ.

НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π΄Π°Ρ‚ΡŒ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ условия Π³Π΄Π΅ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ значСния, Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅, Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ β€” ноль, Π° Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, 42.

Π‘ΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ вычислСния Π·Π° ΠΎΠ΄ΠΈΠ½ запуск Π΄Π°Π΄ΡƒΡ‚ Π½Π°ΠΌ ΠΎΡ‚Π²Π΅Ρ‚, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½Π°ΠΌΠΈ Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π°Π±ΠΎΡ€Π° Ρ‚Π°ΠΊΠΈΡ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². Π›ΠΈΠ±ΠΎ ΠΆΠ΅ Π΄ΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π½Π΅Ρ‚.

Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π΄Π°Ρ‚ΡŒ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π²ΠΎΠΎΠ±Ρ‰Π΅ ΠΊΠ°ΠΊ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅, ΠΈ Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ администратора.

Π’ этом случаС ΠΌΡ‹ Π½Π°ΠΉΠ΄Ρ‘ΠΌ всС уязвимости ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ»ΠΈ ΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π΄ΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π°Π΄ΠΌΠΈΠ½Π° Π² бСзопасности.

МоТно Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ классичСскоС Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ прСдставляСт собой частный случай символьного.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ моя символьная VM ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ эмуляции стандартной Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΌΠ°ΡˆΠΈΠ½Ρ‹.

Π’ коммСнтариях ΠΊ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ ΠΈ ΡΠΏΡ€Π°Π²Π΅Π΄Π»ΠΈΠ²ΡƒΡŽ ΠΊΡ€ΠΈΡ‚ΠΈΠΊΡƒ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с обсуТдСниСм Π΅Ρ‘ слабых мСст.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅:

  1. ΠšΠΎΠΌΠ±ΠΈΠ½Π°Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ Π²Π·Ρ€Ρ‹Π², Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Π°Ρ вСрификация Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΈΡ‚ΠΎΠ³Π΅ упираСтся Π² P=NP
  2. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΊ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС, сСтям ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌ внСшним Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°ΠΌ слоТнСС поддаётся Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
  3. Π‘Π°Π³ΠΈ Π² спСцификации, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊ ΠΈΠ»ΠΈ программист Π·Π°Π΄ΡƒΠΌΠ°Π» ΠΎΠ΄Π½ΠΎ, Π½ΠΎ нСдостаточно Ρ‚ΠΎΡ‡Π½ΠΎ описал это Π² Π’Π—.

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Π²Π΅Ρ€ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π° ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ спСцификации, Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ совсСм Π½Π΅ Ρ‚ΠΎ, Ρ‡Π΅Π³ΠΎ ΠΎΡ‚ Π½Π΅Ρ‘ ΠΆΠ΄Π°Π»ΠΈ создатСли.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ я Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽ Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅, Ρ‚ΠΎ Π±ΠΈΡ‚ΡŒΡΡ Π»Π±ΠΎΠΌ ΠΎ стСну ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Ρƒ, ΠΈ Π²Ρ‹Π±Π΅Ρ€Ρƒ Ρ‚Π°ΠΊΡƒΡŽ систСму, Π³Π΄Π΅ алгоритмичСская ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈ число Π²Π½Π΅ΡˆΠ½ΠΈΡ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² минимально.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ подходят ΠΏΠΎΠ΄ эти трСбования Π½Π°ΠΈΠ»ΡƒΡ‡ΡˆΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π²Ρ‹Π±ΠΎΡ€ ΠΏΠ°Π» Π½Π° ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ RIDE ΠΎΡ‚ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Waves: ΠΎΠ½ΠΈ Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π’ΡŒΡŽΡ€ΠΈΠ½Π³-ΠΏΠΎΠ»Π½Ρ‹ΠΌΠΈ, ΠΈ ΠΈΡ… максимальная ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ искусствСнно ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π°.

Но ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ с тСхничСской стороны.

Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎ всСму, для Π»ΡŽΠ±Ρ‹Ρ… ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ² Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Π°Ρ вСрификация Π±ΡƒΠ΄Π΅Ρ‚ особСнно вострСбована: ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° послС Π΅Π³ΠΎ запуска, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
А Ρ†Π΅Π½Π° Ρ‚Π°ΠΊΠΈΡ… ошибок Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ высока, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π° смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π°Ρ… Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ хранятся довольно ΠΊΡ€ΡƒΠΏΠ½Ρ‹Π΅ суммы срСдств.

Моя символьная Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина написана Π½Π° PHP ΠΈ Python, ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Z3Prover ΠΎΡ‚ Microsoft Research для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΡ…ΡΡ SMT Ρ„ΠΎΡ€ΠΌΡƒΠ».

Π’ Π΅Ρ‘ ядрС Π·Π°Π»ΠΎΠΆΠ΅Π½ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ поиск, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ
позволяСт Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΈΠ»ΠΈ уязвимости, Π΄Π°ΠΆΠ΅ Ссли для этого трСбуСтся ΠΌΠ½ΠΎΠ³ΠΎ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ.
Π”Π°ΠΆΠ΅ Mythril, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· самых ΠΌΠΎΡ‰Π½Ρ‹Ρ… ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ² для поиска уязвимостСй Ethereum, Π΄ΠΎΠ±Π°Π²ΠΈΠ» Ρ‚Π°ΠΊΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ лишь нСсколько мСсяцСв Π½Π°Π·Π°Π΄.

Но стоит Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ эфира слоТнСС ΠΈ ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ Π’ΡŒΡŽΡ€ΠΈΠ½Π³-ΠΏΠΎΠ»Π½ΠΎΡ‚ΠΎΠΉ.

PHP транслируСт исходный ΠΊΠΎΠ΄ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° RIDE Π² python скрипт, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° прСдставлСна Π² Π²ΠΈΠ΄Π΅ совмСстимой с Z3 SMT систСмы состояний ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° ΠΈ условий ΠΈΡ… ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΎΠ²:

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ систСмы Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с нуля. Π§Π°ΡΡ‚ΡŒ 1: символьная Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина Π½Π° PHP ΠΈ Python

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠΏΠΈΡˆΡƒ, Ρ‡Ρ‚ΠΎ происходит Π²Π½ΡƒΡ‚Ρ€ΠΈ, ΠΏΠΎΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅ΠΉ.

Но Π²Π½Π°Ρ‡Π°Π»Π΅ ΠΏΠ°Ρ€Ρƒ слов ΠΎ языкС смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ² RIDE.

Π­Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ основанный Π½Π° выраТСниях язык программирования, Π»Π΅Π½ΠΈΠ²Ρ‹ΠΉ ΠΏΠΎ Π·Π°Π΄ΡƒΠΌΠΊΠ΅.
RIDE выполняСтся ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π°, ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, ΠΈΠ· Π² привязанного ΠΊ ΠΊΠΎΡˆΠ΅Π»ΡŒΠΊΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°.

К ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΊΠΎΡˆΠ΅Π»ΡŒΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ RIDE ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚, ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ TRUE ΠΈΠ»ΠΈ FALSE.

TRUE ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ, Π° FALSE Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π΅Ρ‘ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚.
ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€: скрипт ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄, Π² случаС Ссли баланс кошСлька мСньшС Ρ‡Π΅ΠΌ 100.

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° я Π²ΠΎΠ·ΡŒΠΌΡƒ всё Ρ‚Π΅Ρ… ΠΆΠ΅ Π’ΠΎΠ»ΠΊΠ°, ΠšΠΎΠ·Ρƒ, ΠΈ ΠšΠ°ΠΏΡƒΡΡ‚Ρƒ, Π½ΠΎ ΡƒΠΆΠ΅ прСдставлСнных Π² Π²ΠΈΠ΄Π΅ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π°.

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ смоТСт вывСсти дСньги с кошСлька, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΡ€Π°Π²ΠΈΡ‚ всСх Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π±Π΅Ρ€Π΅Π³.

#ИзвлСкаСм ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ всСх ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΠ· Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π°
let contract = tx.sender
let human= extract(getInteger(contract,"human"))
let wolf= extract(getInteger(contract,"wolf"))
let goat= extract(getInteger(contract,"goat"))
let cabbage= extract(getInteger(contract,"cabbage"))

#Π­Ρ‚ΠΎ Ρ‚Π°ΠΊ называСмая Π΄Π°Ρ‚Π°-транзакция, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ присылаСт Π½ΠΎΠ²Ρ‹Π΅ 4 ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
#ΠšΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ Π΅Ρ‘ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС Ссли всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ останутся Π² сохранности.
match tx {
case t:DataTransaction =>
   #ИзвлСкаСм Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ всСх ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
   let newHuman= extract(getInteger(t.data,"human")) 
   let newWolf= extract(getInteger(t.data,"wolf"))
   let newGoat= extract(getInteger(t.data,"goat"))
   let newCabbage= extract(getInteger(t.data,"cabbage"))
   
   #0 ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π° Π»Π΅Π²ΠΎΠΌ Π±Π΅Ρ€Π΅Π³Ρƒ, Π° 1 Ρ‡Ρ‚ΠΎ Π½Π° ΠΏΡ€Π°Π²ΠΎΠΌ
   let humanSide= human == 0 || human == 1
   let wolfSide= wolf == 0 || wolf == 1
   let goatSide= goat == 0 || goat == 1
   let cabbageSide= cabbage == 0 || cabbage == 1
   let side= humanSide && wolfSide && goatSide && cabbageSide

   #Π‘ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Π³Π΄Π΅ с ΠΊΠΎΠ·ΠΎΠΉ Π½ΠΈΠΊΠΎΠ³ΠΎ Π½Π΅Ρ‚ Π² отсутствии Ρ„Π΅Ρ€ΠΌΠ΅Ρ€Π°.
   let safeAlone= newGoat != newWolf && newGoat != newCabbage
   let safe= safeAlone || newGoat == newHuman
   let humanTravel= human != newHuman 

   #Бпособы ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΡ Ρ„Π΅Ρ€ΠΌΠ΅Ρ€Π° Ρ‚ΡƒΠ΄Π° ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ, с ΠΊΠ΅ΠΌ-Ρ‚ΠΎ Π»ΠΈΠ±ΠΎ Π² ΠΎΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΡƒ.
   let t1= humanTravel && newWolf == wolf + 1 && newGoat == goat && newCabbage == cabbage 
   let t2= humanTravel && newWolf == wolf && newGoat == goat + 1 && newCabbage == cabbage
   let t3= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage + 1
   let t4= humanTravel && newWolf == wolf - 1 && newGoat == goat && newCabbage == cabbage
   let t5= humanTravel && newWolf == wolf && newGoat == goat - 1 && newCabbage == cabbage
   let t6= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage - 1
   let t7= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage
   let objectTravel = t1 || t2 || t3 || t4 || t5 || t6 || t7
   
   #ПослСдняя строка Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ описываСт Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π΅Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ условиС.
   #ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ значСния 1 ΠΈΠ»ΠΈ 0, всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹
   #Π±Ρ‹Ρ‚ΡŒ Π² бСзопасности, Π° Ρ„Π΅Ρ€ΠΌΠ΅Ρ€ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠ΅Ρ€Π΅ΠΏΠ»Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅ΠΊΡƒ Π² ΠΎΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΡƒ 
   #ΠΈΠ»ΠΈ с ΠΊΠ΅ΠΌ-Ρ‚ΠΎ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡˆΠ°Π³Ρƒ
   side && safe && humanTravel && objectTravel
case s:TransferTransaction =>
   #Вранзакция Π²Ρ‹Π²ΠΎΠ΄Π° срСдств Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС Ссли всС ΠΏΠ΅Ρ€Π΅ΠΏΠ»Ρ‹Π»ΠΈ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π±Π΅Ρ€Π΅Π³
   human == 1 && wolf == 1 && goat == 1 && cabbage == 1

#ВсС ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹
case _ => false

}

PHP ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ Π΄Π΅Π»ΠΎΠΌ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ ΠΈΠ· смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° всС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π² Π²ΠΈΠ΄Π΅ ΠΈΡ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ логичСского выраТСния.

cabbage: extract ( getInteger ( contract , "cabbage" ) )
goat: extract ( getInteger ( contract , "goat" ) )
human: extract ( getInteger ( contract , "human" ) )
wolf: extract ( getInteger ( contract , "wolf" ) )
fState: human== 1 && wolf== 1 && goat== 1 && cabbage== 1
fState: 
wolf: 
goat: 
cabbage: 
cabbageSide: cabbage== 0 || cabbage== 1
human: extract ( getInteger ( contract , "human" ) )
newGoat: extract ( getInteger ( t.data , "goat" ) )
newHuman: extract ( getInteger ( t.data , "human" ) )
goatSide: goat== 0 || goat== 1
humanSide: human== 0 || human== 1
t7: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage
t3: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage + 1
t6: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage - 1
t2: humanTravel && newWolf== wolf && newGoat== goat + 1 && newCabbage== cabbage
t5: humanTravel && newWolf== wolf && newGoat== goat - 1 && newCabbage== cabbage
t1: humanTravel && newWolf== wolf + 1 && newGoat== goat && newCabbage== cabbage
t4: humanTravel && newWolf== wolf - 1 && newGoat== goat && newCabbage== cabbage
safeAlone: newGoat != newWolf && newGoat != newCabbage
wolfSide: wolf== 0 || wolf== 1
humanTravel: human != newHuman
side: humanSide && wolfSide && goatSide && cabbageSide
safe: safeAlone || newGoat== newHuman
objectTravel: t1 || t2 || t3 || t4 || t5 || t6 || t7

Π—Π°Ρ‚Π΅ΠΌ PHP ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΈΡ… Π² совмСстимоС с Z3Prover SMT описаниС систСмы Π½Π° ΠΏΠΈΡ‚ΠΎΠ½Π΅.
Π”Π°Π½Π½Ρ‹Π΅ ΠΆΠ΅ Π·Π°Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² Ρ†ΠΈΠΊΠ», Π³Π΄Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ индСкс i, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ индСкс i + 1, Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ с выраТСниями Π·Π°Π΄Π°ΡŽΡ‚ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π° ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ состония Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅.

Π­Ρ‚ΠΎ- самоС сСрдцС нашСй Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΌΠ°ΡˆΠΈΠ½Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈ обСспСчиваСт ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ поиска.

fState:  And( And( And( human[Steps]  ==  1 , wolf[Steps]  ==  1 )  , goat[Steps]  ==  1 )  , cabbage[Steps]  ==  1 )  
final:  fState[Steps] 
fState:   
wolf:   
goat:   
cabbage:   
cabbageSide:  Or( cabbage[i]  ==  0 , cabbage[i]  ==  1 )  
goatSide:  Or( goat[i]  ==  0 , goat[i]  ==  1 )  
humanSide:  Or( human[i]  ==  0 , human[i]  ==  1 )  
t7:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage  ==  cabbage[i] )  
t3:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage  ==  cabbage[i] + 1 )  
t6:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage  ==  cabbage[i] - 1 )  
t2:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] )  , goat[i+1]  ==  goat[i] + 1 )  , cabbage  ==  cabbage[i] )  
t5:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] )  , goat[i+1]  ==  goat[i] - 1 )  , cabbage  ==  cabbage[i] )  
t1:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] + 1 )  , goat[i+1]  ==  goat[i] )  , cabbage  ==  cabbage[i] )  
t4:  And( And( And( humanTravel[i] , wolf  ==  wolf[i] - 1 )  , goat[i+1]  ==  goat[i] )  , cabbage  ==  cabbage[i] )  
safeAlone:  And( goat[i+1] != wolf , goat[i+1] != cabbage )  
wolfSide:  Or( wolf[i]  ==  0 , wolf[i]  ==  1 )  
humanTravel:  human[i] != human[i+1] 
side:  And( And( And( humanSide[i] , wolfSide[i] )  , goatSide[i] )  , cabbageSide[i] )  
safe:  Or( safeAlone[i] , goat[i+1]  ==  human[i+1] )  
objectTravel:  Or( Or( Or( Or( Or( Or( t1[i] , t2[i] )  , t3[i] )  , t4[i] )  , t5[i] )  , t6[i] )  , t7[i] )  
data:  And( And( And( side[i] , safe[i] )  , humanTravel[i] )  , objectTravel[i] )  

Условия ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ Π²ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ Π² шаблон скрипта, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ для описания SMT систСмы Π½Π° ΠΏΠΈΡ‚ΠΎΠ½Π΅.

ΠŸΡƒΡΡ‚ΠΎΠΉ шаблон


import json

from z3 import *

s = Solver()

  
  
    
Steps=7
Num= Steps+1

$code$



#template, only start rest
s.add(data + start)

#template
s.add(final)




ind = 0

f = open("/var/www/html/all/bin/python/log.txt", "a")



while s.check() == sat:
  ind = ind +1
  

  print ind
  m = s.model()
  print m

  print "traversing model..." 
  #for d in m.decls():
	#print "%s = %s" % (d.name(), m[d])

  
 
  f.write(str(m))
  f.write("nn")
  exit()
  #s.add(Or(goat[0] != s.model()[data[0]] )) # prevent next model from using the same assignment as a previous model



print "Total solution number: "
print ind  

f.close()
 


Для послСднСго состояния ΠΈΠ· всСй Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΏΡ€Π°Π²ΠΈΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Π΄Π°Π½Ρ‹ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π°.

А Π·Π½Π°Ρ‡ΠΈΡ‚, Z3Prover Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΊΠ°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊΠΈΠ΅ совокупности состояний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² ΠΈΡ‚ΠΎΠ³Π΅ позволят вывСсти с ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° срСдства.

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ автоматичСски ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ€Π°Π±ΠΎΡ‚ΠΎΡΠΏΠΎΡΠΎΠ±Π½ΡƒΡŽ SMT модСль нашСго ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π°.
МоТно Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° вСсьма ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° модСль ΠΈΠ· ΠΌΠΎΠ΅ΠΉ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ я составлял Π΅Ρ‰Ρ‘ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.

Π—Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΉ шаблон


import json

from z3 import *

s = Solver()

  
  
    
Steps=7
Num= Steps+1

human = [ Int('human_%i' % (i + 1)) for i in range(Num) ]
wolf = [ Int('wolf_%i' % (i + 1)) for i in range(Num) ]
goat = [ Int('goat_%i' % (i + 1)) for i in range(Num) ]
cabbage = [ Int('cabbage_%i' % (i + 1)) for i in range(Num) ]
nothing= [  And( human[i] == human[i+1], wolf[i] == wolf[i+1], goat[i] == goat[i+1], cabbage[i] == cabbage[i+1] )   for i in range(Num-1) ]


start= [ human[0] == 1, wolf[0] == 0, goat[0] == 1, cabbage[0] == 0 ]

safeAlone= [  And( goat[i+1] != wolf[i+1] , goat[i+1] != cabbage[i+1] )   for i in range(Num-1) ]
safe= [  Or( safeAlone[i] , goat[i+1]  ==  human[i+1] )   for i in range(Num-1) ]
humanTravel= [  human[i] != human[i+1]  for i in range(Num-1) ]
cabbageSide= [  Or( cabbage[i]  ==  0 , cabbage[i]  ==  1 )   for i in range(Num-1) ]
goatSide= [  Or( goat[i]  ==  0 , goat[i]  ==  1 )   for i in range(Num-1) ]
humanSide= [  Or( human[i]  ==  0 , human[i]  ==  1 )   for i in range(Num-1) ]
t7= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage[i+1]  ==  cabbage[i] )   for i in range(Num-1) ]
t3= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage[i+1]  ==  cabbage[i] + 1 )   for i in range(Num-1) ]
t6= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] )  , goat[i+1]  ==  goat[i] )  , cabbage[i+1]  ==  cabbage[i] - 1 )   for i in range(Num-1) ]
t2= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] )  , goat[i+1]  ==  goat[i] + 1 )  , cabbage[i+1]  ==  cabbage[i] )   for i in range(Num-1) ]
t5= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] )  , goat[i+1]  ==  goat[i] - 1 )  , cabbage[i+1]  ==  cabbage[i] )   for i in range(Num-1) ]
t1= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] + 1 )  , goat[i+1]  ==  goat[i] )  , cabbage[i+1]  ==  cabbage[i] )   for i in range(Num-1) ]
t4= [  And( And( And( humanTravel[i] , wolf[i+1]  ==  wolf[i] - 1 )  , goat[i+1]  ==  goat[i] )  , cabbage[i+1]  ==  cabbage[i] )   for i in range(Num-1) ]
wolfSide= [  Or( wolf[i]  ==  0 , wolf[i]  ==  1 )   for i in range(Num-1) ]
side= [  And( And( And( humanSide[i] , wolfSide[i] )  , goatSide[i] )  , cabbageSide[i] )   for i in range(Num-1) ]
objectTravel= [  Or( Or( Or( Or( Or( Or( t1[i] , t2[i] )  , t3[i] )  , t4[i] )  , t5[i] )  , t6[i] )  , t7[i] )   for i in range(Num-1) ]
data= [ Or(  And( And( And( side[i] , safe[i] )  , humanTravel[i] )  , objectTravel[i] )   , nothing[i]) for i in range(Num-1) ]


fState=  And( And( And( human[Steps]  ==  1 , wolf[Steps]  ==  1 )  , goat[Steps]  ==  1 )  , cabbage[Steps]  ==  1 )  
final=  fState 




#template, only start rest
s.add(data + start)

#template
s.add(final)




ind = 0

f = open("/var/www/html/all/bin/python/log.txt", "a")



while s.check() == sat:
  ind = ind +1
  

  print ind
  m = s.model()
  print m

  print "traversing model..." 
  #for d in m.decls():
	#print "%s = %s" % (d.name(), m[d])

  
 
  f.write(str(m))
  f.write("nn")
  exit()
  #s.add(Or(goat[0] != s.model()[data[0]] )) # prevent next model from using the same assignment as a previous model



print "Total solution number: "
print ind  

f.close()
 


ПослС запуска, Z3Prover Ρ€Π΅ΡˆΠ°Π΅Ρ‚ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π°ΠΌ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, которая ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ вывСсти срСдства:

Winning transaction chain found:
Data transaction: human= 0, wolf= 0, goat= 1, cabbage= 0
Data transaction: human= 1, wolf= 0, goat= 1, cabbage= 1
Data transaction: human= 0, wolf= 0, goat= 0, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 0, cabbage= 1
Data transaction: human= 0, wolf= 1, goat= 0, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 1, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 1, cabbage= 1
Transfer transaction

ΠšΡ€ΠΎΠΌΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° ΠΏΠ΅Ρ€Π΅ΠΏΡ€Π°Π²Ρ‹, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с собствСнными ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π°ΠΌΠΈ ΠΈΠ»ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ этот простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ Π·Π° 2 Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

let contract = tx.sender
let a= extract(getInteger(contract,"a"))
let b= extract(getInteger(contract,"b"))
let c= extract(getInteger(contract,"c"))
let d= extract(getInteger(contract,"d"))

match tx {
case t:DataTransaction =>
let na= extract(getInteger(t.data,"a")) 
let nb= extract(getInteger(t.data,"b"))
let nc= extract(getInteger(t.data,"c"))
let nd= extract(getInteger(t.data,"d"))
   
   nd == 0 || a == 100 - 5
case s:TransferTransaction =>
   ( a + b - c ) * d == 12

case _ => true

}

Π’Π°ΠΊ ΠΊΠ°ΠΊ это самая пСрвая вСрсия, Ρ‚ΠΎ синтаксис вСсьма ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Ρ‚ΡŒΡΡ Π±Π°Π³ΠΈ.
Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΡΡ‚Π°Ρ‚ΡŒΡΡ… я ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΡŽ ΠΎΡΠ²Π΅Ρ‚ΠΈΡ‚ΡŒ Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΡƒΡŽ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ VM, ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π²Π΅Ρ€ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ с Π΅Ρ‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ ΠΈΡ….

Бимвольная Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина доступна ΠΏΠΎ адрСсу http://2.59.42.98/hyperbox/
ПослС привСдСния исходного ΠΊΠΎΠ΄ символьной VM Π² порядок ΠΈ добавлСния Ρ‚ΡƒΠ΄Π° ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π², я ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΡŽ Π²Ρ‹Π»ΠΎΠΆΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π½Π° Π³ΠΈΡ‚Ρ…Π°Π± Π² свободный доступ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ