Estoy codificando un contrato en el que me gustaría que se llamen algunas funciones solo si lo aprueban 2 personas (un comerciante y un cliente).
Ahora, sé que podría programar un búfer que almacene la solicitud pendiente y esperar a que cada parte envíe una transacción de confirmación.
No quiero que el comerciante actúe sin la aprobación del cliente, pero el problema es que no quiero que el cliente pague la gasolina.
Lo que estaba pensando era de alguna manera hacer solo una transacción, enviada por el comerciante (quien pagará por el gas), pero que pudiera verificar en mi contrato inteligente que la transacción fue firmada por el cliente.
¿Tiene algún consejo sobre cuál es la mejor manera de implementarlo?
Gracias por tus respuestas
Podría usar un enfoque similar a las pruebas de equilibrio en la implementación de canales estatales de Raiden . Básicamente, puede hacer que el cliente firme una confirmación que solo el cliente podría haber firmado y luego verificar esa firma en un contrato de Solidity.
En su ejemplo particular, lo abordaría así:
Vea el código para usar Metamask para firmar datos aquí .
Aquí hay otro ejemplo de multisig de transacción única de Christian Lundkvist. Este esquema está más cerca de Bitcoin multisig que los contratos stateful multisig.
https://medium.com/@ChrisLundkvist/exploring-simpler-ethereum-multisig-contracts-b71020c19037
Código:
pragma solidity 0.4.15;
contract SimpleMultiSig {
uint public nonce; // (only) mutable state
uint public threshold; // immutable state
mapping (address => bool) isOwner; // immutable state
address[] public ownersArr; // immutable state
function SimpleMultiSig(uint threshold_, address[] owners_) {
require(owners_.length <= 10 && threshold_ <= owners_.length && threshold_ != 0);
address lastAdd = address(0);
for (uint i=0; i<owners_.length; i++) {
require(owners_[i] > lastAdd);
isOwner[owners_[i]] = true;
lastAdd = owners_[i];
}
ownersArr = owners_;
threshold = threshold_;
}
// Note that address recovered from signatures must be strictly increasing
function execute(uint8[] sigV, bytes32[] sigR, bytes32[] sigS, address destination, uint value, bytes data) {
require(sigR.length == threshold);
require(sigR.length == sigS.length && sigR.length == sigV.length);
// Follows ERC191 signature scheme: https://github.com/ethereum/EIPs/issues/191
bytes32 txHash = keccak256(byte(0x19), byte(0), this, destination, value, data, nonce);
address lastAdd = address(0); // cannot have address(0) as an owner
for (uint i = 0; i < threshold; i++) {
address recovered = ecrecover(txHash, sigV[i], sigR[i], sigS[i]);
require(recovered > lastAdd && isOwner[recovered]);
lastAdd = recovered;
}
// If we make it here all signatures are accounted for
nonce = nonce + 1;
require(destination.call.value(value)(data));
}
function () payable {}
}