Estoy tratando de crear un contrato de nivel de entrada (uno que sea el punto de entrada):
relé.sol
pragma solidity ^0.4.8;
contract Relay {
address public currentVersion;
address public owner;
modifier onlyOwner() {
if (msg.sender != owner) {
throw;
}
_;
}
function Relay(address initAddr) {
currentVersion = initAddr;
owner = msg.sender;
}
function changeContract(address newVersion) public
onlyOwner()
{
currentVersion = newVersion;
}
function() {
if(!currentVersion.delegatecall(msg.data)) throw;
}
}
y mi contrato
Acceso2.sol
pragma solidity ^0.4.8;
import './Storage.sol';
import './Relay.sol';
contract Access2{
Storage s;
address Storageaddress=0xcd53170a761f024a0441eb15e2f995ae94634c06;
function Access2(){
Relay r=new Relay(this);
}
function createEntity(string entityAddress,uint entityData)public returns(uint rowNumber){
s = Storage(Storageaddress);
uint row=s.newEntity(entityAddress,entityData);
return row;
}
function getEntityCount()public constant returns(uint entityCount){
s = Storage(Storageaddress);
uint count=s.getEntityCount();
return count;
}
}
Ambos contratos están desplegados.
Si accedo al método de Access2 a través de web3 usando el objeto de Access2, funciona bien, pero ahora el problema es cómo puedo acceder al método de Access2 a través de Relay.
¿Puedo usar el Objeto de Relay
?
Esto se verá como un duplicado del contrato actualizable aquí, pero mi pregunta no se trata de escribir un contrato actualizable sino llamar las funciones de nuestro contrato desde el contrato de nivel de entrada: es decir, ¿cómo funciona el concepto de contrato de nivel de entrada?
Gracias por adelantado
Sí, desde Relay
puede llamar a Access2
funciones, como createEntity
.
El código importante Relay
que lo hace posible es su función alternativa :
function() {
if(!currentVersion.delegatecall(msg.data)) throw;
}
Es útil leer las preguntas y respuestas sobre la función de reserva para aprender más sobre ellas.
Básicamente, cuando invoca (llama) createEntity
en Relay
, porque Relay
no tiene una createEntity
función, Relay
se llamará a la función alternativa de. El valor de currentVersion
es su instancia de Access2
, por lo que funcionará delegatecall(msg.data)
en esa Access2
instancia. msg.data
contiene la información que luego invocará la createEntity
función en esa Access2
instancia.
Otra forma de decirlo: solicita Relay
ejecutar algunos datos (función de llamada createEntity
con ciertos datos y argumentos), pero como Relay
no sabe cómo manejar esos datos, pasará los datos a Access2
.
Basically, when you invoke (call) createEntity in Relay, because Relay doesn't have a createEntity function, the fallback function of Relay will be called.
¿Cuál será el comando web3 para invocar createEntity en retransmisión?web3.eth.sendTransaction
. El data
correspondiente a la llamada createEntity
deberá especificarse de acuerdo con el abi .Sí, puede usar una instancia de su Relay
contrato para llamar funciones de la instancia vinculada del Access2
contrato.
Creé el siguiente ejemplo mínimo que podrías probar en Remix :
contract target {
event something();
function doSomething() {
something();
}
}
contract relay {
target myTarget;
function relay() {
// this will deploy a new target contract, you could also just set its address
myTarget = new target();
}
function relayCall() {
myTarget.doSomething();
}
}
Para probar esto, puede crear una instancia de relay
(que crea una instancia de target
en su constructor). Cuando lo llame relayCall
, llamará a la doSomething
función de esa target
instancia. Verá correspondientemente el evento something
que se está llamando.
No es que importe, pero para completar: hay un pequeño problema en su Access2
contrato:
function Access2(){
Relay r=new Relay(this);
}
Aquí this
está la dirección de la instancia actual de Access2
(que no es de tipo Relay
). Como no llamas a nada en ese r
objeto, todo está bien. Pero lo más probable es que tenga errores de tiempo de ejecución al intentar acceder a funciones que no existen (ya que asigna una Access2
instancia a un objeto de tipo Relay
).
niksmac
SwapnilKumbhar
mike b