์ฒ˜์Œ๋ถ€ํ„ฐ ๊ณต์‹ ๊ฒ€์ฆ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 1๋ถ€: PHP ๋ฐ Python์˜ ๋ฌธ์ž ๊ฐ€์ƒ ๋จธ์‹ 

๊ณต์‹ ๊ฒ€์ฆ์€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ์ทจ์•ฝ์ ์„ ์ฐพ๊ฑฐ๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š์Œ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

ํ˜•์‹ ๊ฒ€์ฆ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ์˜ˆ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Š‘๋Œ€์™€ ์—ผ์†Œ์™€ ์–‘๋ฐฐ์ถ” ๋‚ด ์ด์ „ ๊ธฐ์‚ฌ์—์„œ.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๋ฌธ์ œ์˜ ๊ณต์‹ ๊ฒ€์ฆ์—์„œ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ์ด๋™ํ•˜๊ณ  ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
์–ด๋–ป๊ฒŒ ์ž๋™์œผ๋กœ ๊ณต์‹ ๊ทœ์น™ ์‹œ์Šคํ…œ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๋ฅผ ์œ„ํ•ด ๋‚˜๋Š” ์ƒ์ง•์  ์›๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ƒ ๋จธ์‹ ์˜ ์•„๋‚ ๋กœ๊ทธ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์—ฌ ์ด๋ฏธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํ’€ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์ •์‹ ์‹œ์Šคํ…œ(SMT)์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐํ˜ธ๊ณ„์‚ฐ์— ๊ด€ํ•œ ์ •๋ณด๋Š” ์ธํ„ฐ๋„ท์ƒ์— ๋‹ค์†Œ ๋‹จํŽธ์ ์œผ๋กœ ์ œ์‹œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—,
๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐํ˜ธ๊ณ„์‚ฐ์€ ๊ด‘๋ฒ”์œ„ํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ํ”„๋กœ๊ทธ๋žจ์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ๊ณต์‹์ ์ธ ํ”„๋กœ๊ทธ๋žจ ๊ฒ€์ฆ์„ ์œ„ํ•œ ์ฃผ์š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์–‘์ˆ˜ ๊ฐ’, ๋‘ ๋ฒˆ์งธ ์Œ์ˆ˜, ์„ธ ๋ฒˆ์งธ 42, ์ถœ๋ ฅ ์ธ์ˆ˜(์˜ˆ: XNUMX)๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ๋Š” ์ž…๋ ฅ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ ๋ฒˆ์˜ ์‹คํ–‰์œผ๋กœ ๊ธฐํ˜ธ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•œ ๋‹ต๊ณผ ์ด๋Ÿฌํ•œ ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ง‘ํ•ฉ์˜ ์˜ˆ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๊ทธ๋Ÿฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค๋Š” ์ฆ๊ฑฐ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์ž…๋ ฅ ์ธ์ˆ˜๋ฅผ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ธ์ˆ˜๋กœ ์„ค์ •ํ•˜๊ณ  ์ถœ๋ ฅ ์ธ์ˆ˜(์˜ˆ: ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ)๋งŒ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ์ทจ์•ฝ์ ์„ ์ฐพ์•„๋‚ด๊ฑฐ๋‚˜ ๊ด€๋ฆฌ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์•ˆ์ „ํ•˜๋‹ค๋Š” ์ฆ๊ฑฐ๋ฅผ ํ™•๋ณดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํŠน์ • ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ณ ์ „์ ์ธ ์‹คํ–‰์€ ๊ธฐํ˜ธ ์‹คํ–‰์˜ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋ผ๋Š” ์ ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‚ด ์บ๋ฆญํ„ฐ VM์€ ํ‘œ์ค€ ๊ฐ€์ƒ ๋จธ์‹ ์˜ ์—๋ฎฌ๋ ˆ์ด์…˜ ๋ชจ๋“œ์—์„œ๋„ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ „ ๊ธฐ์‚ฌ์— ๋Œ€ํ•œ ๋…ผํ‰์—์„œ ๊ณต์‹์ ์ธ ๊ฒ€์ฆ์˜ ์•ฝ์ ์— ๋Œ€ํ•œ ๋…ผ์˜์™€ ํ•จ๊ป˜ ๊ณต์ •ํ•œ ๋น„ํŒ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๊ณต์‹ ๊ฒ€์ฆ์ด ๊ถ๊ทน์ ์œผ๋กœ P=NP๋กœ ๊ท€๊ฒฐ๋˜๋ฏ€๋กœ ์กฐํ•ฉ ํญ๋ฐœ
  2. ํŒŒ์ผ ์‹œ์Šคํ…œ, ๋„คํŠธ์›Œํฌ ๋ฐ ๊ธฐํƒ€ ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ํ˜ธ์ถœ ์ฒ˜๋ฆฌ๋ฅผ ํ™•์ธํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  3. ๊ณ ๊ฐ์ด๋‚˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ํ•œ ๊ฐ€์ง€๋ฅผ ์˜๋„ํ–ˆ์ง€๋งŒ ๊ธฐ์ˆ  ์‚ฌ์–‘์—์„œ ์ด๋ฅผ ์ถฉ๋ถ„ํžˆ ์ •ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์‚ฌ์–‘์˜ ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์€ ์‚ฌ์–‘์„ ๊ฒ€์ฆํ•˜๊ณ  ์ค€์ˆ˜ํ•˜์ง€๋งŒ ์ œ์ž‘์ž๊ฐ€ ๊ธฐ๋Œ€ํ–ˆ๋˜ ๊ฒƒ๊ณผ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์‹ค์ œ๋กœ ํ˜•์‹ ๊ฒ€์ฆ์˜ ์‚ฌ์šฉ์„ ์ฃผ๋กœ ๊ณ ๋ คํ•˜๋ฏ€๋กœ ์ง€๊ธˆ์€ ๋ฒฝ์— ๋ถ€๋”ช์น˜์ง€ ์•Š๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณต์žก์„ฑ๊ณผ ์™ธ๋ถ€ ํ˜ธ์ถœ ์ˆ˜๊ฐ€ ์ตœ์†Œํ™”๋˜๋Š” ์‹œ์Šคํ…œ์„ ์„ ํƒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์Šค๋งˆํŠธ ๊ณ„์•ฝ์€ ์ด๋Ÿฌํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์— ๊ฐ€์žฅ ์ ํ•ฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Waves ํ”Œ๋žซํผ์˜ RIDE ๊ณ„์•ฝ์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Turing ์™„์ „ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ตœ๋Œ€ ๋ณต์žก์„ฑ์ด ์ธ์œ„์ ์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ธฐ์ˆ ์  ์ธก๋ฉด์—์„œ๋งŒ ์ด๋ฅผ ๊ณ ๋ คํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒƒ ์™ธ์—๋„ ๋ชจ๋“  ๊ณ„์•ฝ์— ๋Œ€ํ•ด ๊ณต์‹์ ์ธ ๊ฒ€์ฆ์ด ํŠนํžˆ ์š”๊ตฌ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ณ„์•ฝ์ด ์‹œ์ž‘๋œ ํ›„์—๋Š” ๊ณ„์•ฝ ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๊ทธ๋Ÿฌํ•œ ์˜ค๋ฅ˜๋กœ ์ธํ•œ ๋น„์šฉ์€ ๋งค์šฐ ๋†’์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฝค ๋งŽ์€ ์–‘์˜ ์ž๊ธˆ์ด ์Šค๋งˆํŠธ ๊ณ„์•ฝ์— ์ €์žฅ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด ๊ธฐํ˜ธ ๊ฐ€์ƒ ๋จธ์‹ ์€ PHP์™€ Python์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ Microsoft Research์˜ Z3Prover๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ SMT ๊ณต์‹์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ํ•ต์‹ฌ์—๋Š” ๊ฐ•๋ ฅํ•œ ๋‹ค์ค‘ ํŠธ๋žœ์žญ์…˜ ๊ฒ€์ƒ‰์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŽ์€ ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋„ ์†”๋ฃจ์…˜์ด๋‚˜ ์ทจ์•ฝ์ ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์กฐ์ฐจ ๋ฏธ์Šค๋ฆด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๋Š” ์ด๋ฅผ Python์˜ 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] )  

์กฐ๊ฑด์€ ์ •๋ ฌ๋˜์–ด Python์˜ 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์˜ ์ถ”๊ฐ€ ๊ฐœ๋ฐœ์— ๋Œ€ํ•ด ๋‹ค๋ฃจ๊ณ  VM์˜ ๋„์›€์„ ๋ฐ›์•„ ๋‹จ์ˆœํžˆ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ณต์‹์ ์œผ๋กœ ๊ฒ€์ฆ๋œ ์Šค๋งˆํŠธ ๊ณ„์•ฝ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค„ ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

์บ๋ฆญํ„ฐ ๊ฐ€์ƒ๋จธ์‹ ์€ ๋‹ค์Œ์—์„œ ์ด์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. http://2.59.42.98/hyperbox/
์‹ฌ๋ณผ๋ฆญ VM์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๊ฑฐ๊ธฐ์— ์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„ GitHub์— ์˜ฌ๋ ค ๋ฌด๋ฃŒ๋กœ ์ ‘๊ทผํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€