Yasal Anlaşmalar için Akıllı Sözleşme: Sağlamlık ve Vyper
2025'te Arizona ve Wyoming, sözleşmelerin kanunlaştırıldığını açıkça kabul etti. akıllı sözleşmelerde gereklilikleri karşılamaları halinde yasal olarak bağlayıcı değere sahip olabilirler Sözleşme hukukunun geleneksel yönleri: Teklif, kabul, tarafların sebepleri ve ehliyetleri. Ancak kritik ayrım hâlâ devam ediyor: Bir akıllı sözleşmeler ve bir program ki önceden tanımlanmış koşulları otomatik olarak yürütür; A yasal sözleşme ve bir anlaşma taraflar arasında bağlayıcıdır. Her akıllı sözleşme yasal bir sözleşme değildir ve her anlaşma da yasal bir sözleşme değildir Akıllı sözleşmeyle yasal ve otomatikleştirilebilir.
Bu makalede akıllı sözleşmelerin anlaşmalara yönelik pratik uygulamasını araştırıyoruz gerçek yasal: otomatik emanet, koşullu ödeme, zincir üzerinde yaptırıma sahip NDA'lar, ve her durumda hukuki sonuçlar. Kod, karşılaştırmalı olarak Solidity'de (Ethereum) bulunmaktadır Yüksek güvenlikli kullanım durumları için Vyper ile.
Ne Öğreneceksiniz
- Akıllı sözleşme ile yasal sözleşme arasındaki fark: ne zaman çalışır ve ne zaman çalışmaz
- Solidity'de otomatik emanet modeli
- Şartlı ödeme sözleşmesi (teslimatta ödeme)
- Yüksek güvenlikli akıllı sözleşmeler için Vyper: Solidity'ye karşı avantajlar
- Hardhat ve Foundry ile test etme
- Güvenlik denetimleri: yaygın güvenlik açıkları ve bunlardan nasıl kaçınılacağı
- Yasal paket: akıllı sözleşmelerin geleneksel sözleşmelere bağlanması
Akıllı Sözleşme Yasal Anlamda Olduğunda
Akıllı sözleşmeler aşağıdaki senaryolarda öne çıkar:
- Koşullar zincir üzerinde objektif olarak doğrulanabilir: ödeme geldi (blockchain olayı), son kullanma tarihi geçti (blok zaman damgası), bir NFT aktarılır.
- Taraflar birbirlerine güvenmiyor ve ortadan kaldırmak istiyorlar aracı (banka, noter, emanet acentesi).
- Otomatik ve istenen yürütme: hiçbir parti olmamalı Yükümlülüğünüzü yerine getirmek için manuel olarak "etkinleştirin".
Akıllı sözleşmeler aşağıdakiler için uygun değildir:
- Zincir üzerinde doğrulanamayan gerçek dünya olaylarına dayanan anlaşmalar (örneğin, "mallar iyi durumda geldi") - güvenilir kehanetler gerektirir.
- Tarafların öznel yorumunu veya müzakeresini gerektiren sözleşmeler.
- Bir tarafın geçerliliğine itiraz etme nedeninin bulunabileceği bağlamlar kodun kendisi.
Desen 1: Otomatik Emanet
Emanet, yasal akıllı sözleşmeler için en doğal kullanım durumudur: bir alıcı yalnızca bir koşul yerine getirildiğinde satıcıya verilen parayı yatırır spesifikasyon (onaylanmış teslimat, onaylanmış kilometre taşı). Uyuşmazlık durumunda hakem önceden belirlenmiş karar verir.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**
* @title LegalEscrow
* @notice Contratto di escrow per accordi commerciali.
* @dev Collega automaticamente pagamento a consegna verificata.
* Non sostituisce un accordo contrattuale scritto:
* usare come complemento tecnico a un contratto tradizionale.
*/
contract LegalEscrow {
// --- Tipi ---
enum EscrowState { Created, Funded, Delivered, Disputed, Released, Refunded }
struct EscrowAgreement {
address payable buyer;
address payable seller;
address arbiter; // arbitro per le dispute
uint256 amount; // importo in wei
uint256 releaseAfter; // timestamp dopo cui il buyer può forzare il rilascio
EscrowState state;
string legalContractHash; // SHA-256 del contratto legale allegato
string description;
}
// --- Storage ---
mapping(uint256 => EscrowAgreement) public agreements;
uint256 private nextAgreementId;
// --- Events ---
event AgreementCreated(uint256 indexed id, address buyer, address seller, uint256 amount);
event Funded(uint256 indexed id, uint256 amount);
event DeliveryConfirmed(uint256 indexed id, address confirmedBy);
event DisputeRaised(uint256 indexed id, address raisedBy, string reason);
event ArbiterDecision(uint256 indexed id, bool releasedToSeller);
event FundsReleased(uint256 indexed id, address recipient, uint256 amount);
// --- Modificatori ---
modifier onlyBuyer(uint256 id) {
require(msg.sender == agreements[id].buyer, "Solo il buyer può eseguire questa azione");
_;
}
modifier onlySeller(uint256 id) {
require(msg.sender == agreements[id].seller, "Solo il seller può eseguire questa azione");
_;
}
modifier onlyArbiter(uint256 id) {
require(msg.sender == agreements[id].arbiter, "Solo l'arbitro può eseguire questa azione");
_;
}
modifier inState(uint256 id, EscrowState expected) {
require(agreements[id].state == expected, "Operazione non valida nello stato corrente");
_;
}
// --- Funzioni ---
/**
* @notice Crea un nuovo accordo di escrow.
* @param seller Indirizzo del venditore
* @param arbiter Indirizzo dell'arbitro (notaio, avvocato, DAO di arbitrato)
* @param legalContractHash Hash SHA-256 del contratto PDF allegato off-chain
* @param description Descrizione dell'accordo
* @param daysToAutoRelease Giorni dopo i quali il buyer può forzare il rilascio
*/
function createAgreement(
address payable seller,
address arbiter,
string calldata legalContractHash,
string calldata description,
uint256 daysToAutoRelease
) external returns (uint256 agreementId) {
require(seller != address(0) && arbiter != address(0), "Indirizzi non validi");
require(seller != msg.sender, "Buyer e seller non possono coincidere");
agreementId = nextAgreementId++;
agreements[agreementId] = EscrowAgreement({
buyer: payable(msg.sender),
seller: seller,
arbiter: arbiter,
amount: 0,
releaseAfter: block.timestamp + (daysToAutoRelease * 1 days),
state: EscrowState.Created,
legalContractHash: legalContractHash,
description: description
});
emit AgreementCreated(agreementId, msg.sender, seller, 0);
}
/**
* @notice Il buyer finanzia l'escrow inviando ETH.
*/
function fund(uint256 id)
external
payable
onlyBuyer(id)
inState(id, EscrowState.Created)
{
require(msg.value > 0, "Importo deve essere maggiore di zero");
agreements[id].amount = msg.value;
agreements[id].state = EscrowState.Funded;
emit Funded(id, msg.value);
}
/**
* @notice Il buyer conferma la consegna e rilascia i fondi al seller.
*/
function confirmDelivery(uint256 id)
external
onlyBuyer(id)
inState(id, EscrowState.Funded)
{
agreements[id].state = EscrowState.Released;
agreements[id].seller.transfer(agreements[id].amount);
emit DeliveryConfirmed(id, msg.sender);
emit FundsReleased(id, agreements[id].seller, agreements[id].amount);
}
/**
* @notice Il buyer o il seller apre una disputa.
*/
function raiseDispute(uint256 id, string calldata reason)
external
inState(id, EscrowState.Funded)
{
require(
msg.sender == agreements[id].buyer || msg.sender == agreements[id].seller,
"Solo buyer o seller possono aprire una disputa"
);
agreements[id].state = EscrowState.Disputed;
emit DisputeRaised(id, msg.sender, reason);
}
/**
* @notice L'arbitro risolve la disputa.
* @param releaseToSeller true = fondi al seller, false = rimborso al buyer
*/
function resolve(uint256 id, bool releaseToSeller)
external
onlyArbiter(id)
inState(id, EscrowState.Disputed)
{
uint256 amount = agreements[id].amount;
agreements[id].state = releaseToSeller ? EscrowState.Released : EscrowState.Refunded;
if (releaseToSeller) {
agreements[id].seller.transfer(amount);
emit FundsReleased(id, agreements[id].seller, amount);
} else {
agreements[id].buyer.transfer(amount);
emit FundsReleased(id, agreements[id].buyer, amount);
}
emit ArbiterDecision(id, releaseToSeller);
}
}
Model 2: Oracle ile Koşullu Ödeme
Pek çok yasal anlaşma doğrudan doğruya gerçekleşmeyen gerçek dünya olaylarına dayanmaktadır. zincir üzerinde doğrulanabilir: "ürün İtalya'ya ulaştı", "KPI'ya ulaşıldı", "patent onaylandı". kehanet (Chainlink en yaygın olanıdır) zincir dışı verileri doğrulanabilir bir şekilde blok zincirine getirirler.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
/**
* @title ConditionalPayment
* @notice Pagamento condizionale: si sblocca quando un KPI supera una soglia.
* Esempio: bonus al fornitore quando il tasso di soddisfazione cliente > 4.5/5
*/
contract ConditionalPayment {
address payable public beneficiary; // chi riceve il pagamento
address public payer; // chi ha depositato i fondi
uint256 public threshold; // soglia KPI (in base agli accordi)
uint256 public depositedAmount;
bool public paid;
// Oracle Chainlink per il KPI (es. customer satisfaction score)
AggregatorV3Interface internal kpiOracle;
event PaymentReleased(address to, uint256 amount, int256 kpiValue);
event PaymentRefunded(address to, uint256 amount, int256 kpiValue);
constructor(
address payable _beneficiary,
uint256 _threshold,
address _oracleAddress // indirizzo del price feed / data feed Chainlink
) {
payer = msg.sender;
beneficiary = _beneficiary;
threshold = _threshold;
kpiOracle = AggregatorV3Interface(_oracleAddress);
}
function deposit() external payable {
require(msg.sender == payer, "Solo il payer può depositare");
require(msg.value > 0, "Importo deve essere positivo");
depositedAmount = msg.value;
}
function checkAndPay() external {
require(!paid, "Pagamento già eseguito");
require(depositedAmount > 0, "Nessun fondo depositato");
// Leggi il valore del KPI dall'oracle Chainlink
(, int256 kpiValue, , ,) = kpiOracle.latestRoundData();
paid = true;
if (uint256(kpiValue) >= threshold) {
// KPI raggiunto: paga il beneficiario
beneficiary.transfer(depositedAmount);
emit PaymentReleased(beneficiary, depositedAmount, kpiValue);
} else {
// KPI non raggiunto: rimborsa il payer
payable(payer).transfer(depositedAmount);
emit PaymentRefunded(payer, depositedAmount, kpiValue);
}
}
}
Yüksek Güvenlikli Akıllı Sözleşmeler için Vyper
Yüksek değerli yasal anlaşmalar için birçok ekip tercih ediyor Engerek Sağlamlıkta güvenlik nedeniyle. Vyper, EVM için Python benzeri bir programlama dilidir. Solidity'de bulunan bazı güvenlik açığı sınıflarını tasarım yoluyla ortadan kaldırır: miras yok, aşırı yükleme yok, özyineleme yok, dizilerde dinamik değişiklik yok.
# @version 0.3.10
# @title SimpleEscrow - Vyper version
# @notice Implementazione Vyper dell'escrow per alta sicurezza.
# Vyper e più verboso ma più leggibile e auditable di Solidity.
# --- Strutture Dati ---
struct Agreement:
buyer: address
seller: address
amount: uint256
released: bool
refunded: bool
disputed: bool
# --- Storage ---
agreements: HashMap[uint256, Agreement]
agreement_count: uint256
owner: address
# --- Events ---
event Funded: indexed(agreement_id: uint256, amount: uint256)
event Released: indexed(agreement_id: uint256)
event Disputed: indexed(agreement_id: uint256)
# --- Costruttore ---
@external
def __init__():
self.owner = msg.sender
self.agreement_count = 0
# --- Funzioni ---
@external
def create_agreement(seller: address) -> uint256:
"""Crea un nuovo accordo di escrow."""
assert seller != msg.sender, "Buyer e seller non possono coincidere"
assert seller != empty(address), "Seller non valido"
agreement_id: uint256 = self.agreement_count
self.agreements[agreement_id] = Agreement({
buyer: msg.sender,
seller: seller,
amount: 0,
released: False,
refunded: False,
disputed: False
})
self.agreement_count += 1
return agreement_id
@external
@payable
def fund(agreement_id: uint256):
"""Il buyer finanzia l'escrow."""
agreement: Agreement = self.agreements[agreement_id]
assert agreement.buyer == msg.sender, "Solo il buyer può finanziare"
assert msg.value > 0, "Importo deve essere positivo"
assert agreement.amount == 0, "Accordo già finanziato"
self.agreements[agreement_id].amount = msg.value
log Funded(agreement_id, msg.value)
@external
def release(agreement_id: uint256):
"""Il buyer rilascia i fondi al seller."""
agreement: Agreement = self.agreements[agreement_id]
assert agreement.buyer == msg.sender, "Solo il buyer può rilasciare"
assert not agreement.released, "Gia rilasciato"
assert not agreement.disputed, "In corso di disputa"
assert agreement.amount > 0, "Nessun fondo depositato"
amount: uint256 = agreement.amount
self.agreements[agreement_id].released = True
self.agreements[agreement_id].amount = 0
send(agreement.seller, amount)
log Released(agreement_id)
Hardhat ile test etme
Eksiksiz bir test paketi olmadan hiçbir akıllı sözleşme üretime geçmemelidir. Hardhat, Ethereum akıllı sözleşmeleri için standart geliştirme ortamıdır. TypeScript için ve Ethers.js ile test etmek için.
import { ethers } from "hardhat";
import { expect } from "chai";
import { LegalEscrow } from "../typechain-types";
describe("LegalEscrow", function () {
let escrow: LegalEscrow;
let buyer: any, seller: any, arbiter: any, other: any;
beforeEach(async function () {
[buyer, seller, arbiter, other] = await ethers.getSigners();
const EscrowFactory = await ethers.getContractFactory("LegalEscrow");
escrow = await EscrowFactory.deploy() as LegalEscrow;
});
describe("Happy path: buyer conferma consegna", function () {
it("dovrebbe rilasciare i fondi al seller dopo conferma", async function () {
// Crea accordo
const tx = await escrow.connect(buyer).createAgreement(
seller.address, arbiter.address,
"abc123sha256hash", "Fornitura software", 30
);
const receipt = await tx.wait();
const agreementId = 0;
// Buyer finanzia
const amount = ethers.parseEther("1.0");
await escrow.connect(buyer).fund(agreementId, { value: amount });
// Verifica saldo seller prima
const sellerBalanceBefore = await ethers.provider.getBalance(seller.address);
// Buyer conferma consegna
await escrow.connect(buyer).confirmDelivery(agreementId);
// Verifica saldo seller dopo: deve essere aumentato
const sellerBalanceAfter = await ethers.provider.getBalance(seller.address);
expect(sellerBalanceAfter - sellerBalanceBefore).to.equal(amount);
});
});
describe("Dispute path: arbitro risolve a favore buyer", function () {
it("dovrebbe rimborsare il buyer su decisione dell'arbitro", async function () {
const agreementId = 0;
const amount = ethers.parseEther("2.0");
await escrow.connect(buyer).createAgreement(
seller.address, arbiter.address, "hash456", "Consulenza", 30
);
await escrow.connect(buyer).fund(agreementId, { value: amount });
await escrow.connect(buyer).raiseDispute(agreementId, "Deliverable non conforme");
const buyerBalanceBefore = await ethers.provider.getBalance(buyer.address);
await escrow.connect(arbiter).resolve(agreementId, false); // false = rimborso buyer
const buyerBalanceAfter = await ethers.provider.getBalance(buyer.address);
expect(buyerBalanceAfter - buyerBalanceBefore).to.be.closeTo(amount, ethers.parseEther("0.01"));
});
});
describe("Sicurezza: accessi non autorizzati", function () {
it("dovrebbe rigettare confirmDelivery da non-buyer", async function () {
await escrow.connect(buyer).createAgreement(
seller.address, arbiter.address, "hash789", "Test", 30
);
await escrow.connect(buyer).fund(0, { value: ethers.parseEther("1.0") });
await expect(
escrow.connect(other).confirmDelivery(0)
).to.be.revertedWith("Solo il buyer può eseguire questa azione");
});
});
});
Yaygın Güvenlik Açıkları ve Güvenlik
Yasal Akıllı Sözleşmelerdeki Kritik Güvenlik Açıkları
- Yeniden giriş: çağrı/aktarım modeli bir sözleşmeyi mümkün kılabilir durum güncellenmeden önce işlevi tekrar çağırmak için kötü amaçlıdır. Her zaman OpenZeppelin'in kontrol-etki-etkileşimlerini ve ReentrancyGuard modelini kullanın.
- Tamsayı taşması/eksikliği: Solidity'nin 0.8 öncesi döneminde bu yaygındı; itibaren sürüm 0.8 aritmetik işlemler otomatik olarak geri alınır. Her zaman kullan Sağlamlık 0,8+.
- Oracle manipülasyonu: sözleşme bir kehanete bağlıysa, Gelişmiş saldırgan, Oracle verilerini manipüle edebilir (örneğin, flaş kredi + fiyat kahini). Chainlink'i zaman ağırlıklı ortalama fiyatlarla (TWAP) kullanın.
- Ön koşu: işlemler ilk olarak bellek havuzunda görünür onaylanması. Sıranın önemli olduğu anlaşmalar için taahhüt-açıklama şemasını kullanın.
- Hata Değişmezliği: geleneksel yazılımlardan farklı olarak Akıllı sözleşmedeki bir hata, dağıtım sonrasında "düzeltilemez". Desenleri kullan yükseltilebilir proxy'ler (EIP-1967) veya acil durumlar için bir dondurma mekanizması ekleyin.
Yasal Paket: Gerçek Dünyayla Bağlantı
Akıllı sözleşme tek başına taraflar arasında yasal yükümlülük yaratmaz. A. ihtiyaç var yasal sarmalayıcılar: Geleneksel bir sözleşmeye dayalı anlaşma:
- Sözleşme taraflarını gerçek kişisel verilerle tanımlayın
- X adresindeki akıllı sözleşmeyi ve yürütme mekanizmasını belirtir sözleşmede açıklanan anlaşmanın
- Uyuşmazlıklar için geçerli yargı yetkisini ve yerini tanımlar
- Referans için sözleşme kaynak kodunun SHA-256 karmasını içerir
- Akıllı sözleşmede bir hata veya beklenmeyen bir davranış olması durumunda ne olacağını belirler
Sonuçlar
Yasal anlaşmalara yönelik akıllı sözleşmeler güçlü bir araçtır ancak şunları gerektirir: Uygun kullanım durumlarını belirlemek için dikkatli bir tasarım, bir kod Yüksek güvenlik standartlarıyla yazılmış, kapsamlı testlerle denetlenmiş, blockchain güvenlik uzmanları ve onları sisteme bağlayan yasal bir paket geleneksel yasal.
Yasal akıllı sözleşmelerin geleceği, geleneksel sözleşmelerin yerini almak değildir. ancak bunların tamamlayıcısı: en karmaşık ticaret anlaşmaları hibrit olacak, Zincir üzerinde otomatik olarak çalıştırılabilen maddeler ve yönetilen yorumlayıcı maddeler ile insan hakemler tarafından.
LegalTech ve AI serisi
- Sözleşme Analizi için NLP: OCR'den Anlamaya
- e-Keşif Platformu Mimarisi
- Dinamik Kural Motoru ile Uyumluluk Otomasyonu
- Yasal Anlaşmalar için Akıllı Sözleşme: Sağlamlık ve Vyper (bu makale)
- Üretken Yapay Zeka ile Yasal Belgelerin Özetlenmesi
- Arama Motoru Yasası: Vektör Yerleştirmeleri
- Scala'da Dijital İmza ve Belge Kimlik Doğrulaması
- Veri Gizliliği ve GDPR Uyumluluk Sistemleri
- Yasal Yapay Zeka Asistanı Oluşturma (Yasal Yardımcı Pilot)
- LegalTech Veri Entegrasyon Modeli







