Advertisement
Guest User

Untitled

a guest
Jun 19th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.68 KB | None | 0 0
  1. pragma solidity ^0.4.6;
  2.  
  3. //Para este trabalho, os atores "Manufaturador", "Transportador", "Armazem" e "Produtor" são considerados entidades importantes para refererência ao rastrear
  4. // a cadeia. Por este motivo, foi criado este contrato genérico no qual será herdado por todas esses contratos, que serão empresas;
  5. contract Empresa{
  6. //O nome da empresa;
  7. string nome;
  8. // O Endereco se refere a "Account" neste caso;
  9. address endereco;
  10.  
  11. }
  12.  
  13. // Esta implementação ainda não está ideal, o objetivo de criar o "Estoque" como algo abstrato é para reduzir redundância nas contratos que tem como natureza
  14. // "estocar" algum produto produzido que será posteriormente processado. Estou ciente que o nome não é dos mais adequados, então sugiro a modificação deste
  15. // nome para trabalhos posteriores. No caso, ela será herdada pelo "Produtor", pelo "Manufaturador" e pelo "Armazém", visto que todos eles possuem a característica
  16. // de armazenar e encaminhar produtos para uma outra empresa;
  17. contract Estoque{
  18.  
  19. // Esta variável, estoque, será responsavel por identificar os produtos que serão encaminhados para uma unidade posterior;
  20. Produto[] estoque;
  21. // Esta variável sera o identificador da "Account" do destino do produto;
  22. address destinoProduto;
  23.  
  24. // Essa função tem como objetivo atualizar/definir o destino atual do conteúdo em estoque.
  25. function setDestino(address _enderecoArmazem) public {
  26. destinoProduto = _enderecoArmazem;
  27. }
  28.  
  29. // Essa função utiliza a "Account" de algum transportador no qual será responsável pelo transporte;
  30. function encaminha(Transportadora transportadorResponsavel) public{
  31. // O "Pacote" será explicado posteriormente. Ele é só um contrato onde possuí um produto e um destino, assim o transportador
  32. // pode transportar para outro transportador sem problemas. Para criar o pacote, utiliza-se o produto no topo do array de produtos
  33. // e o destino do produto;
  34. Pacote pacoteParaEntrega= new Pacote(destinoProduto, estoque[estoque.length-1]);
  35. // Tratamento do array de produtos;
  36. delete estoque[estoque.length-1];
  37. estoque.length--;
  38. // Encaminha o pacote para o transportador realizar a entrega;
  39. transportadorResponsavel.entrega(pacoteParaEntrega);
  40. }
  41.  
  42. // Esta função está mal implementada. Contudo, quando deixada ela de forma abstrata ( sem as chaves), o programa não compilava mesmo depois de definir
  43. // explicitamente a função dentro das outras que herdam esse contrato. Não foi possível solucionar o problema durante o tempo do trabalho.
  44. function recebe(Produto _produtoRecebido) public{
  45. }
  46.  
  47. }
  48.  
  49. // O produtor, conforme definido no planejamento, é um tipo especial de Manufaturador, ele não possuí nenhuma matéria prima como insumo, então ele pode produzir
  50. // "produtos" a partir do "nada"
  51. contract Produtor is Empresa, Estoque{
  52.  
  53. // Seu construtor se restringe a definir os seus atributos herdados de "Empresa", visto que o Produtor é uma empresa relevante para o rastreamento.
  54. constructor(string _nome) public {
  55. nome = _nome;
  56. endereco = msg.sender;
  57. }
  58.  
  59. // Este método simplesmente produz o "Produto" matéria prima, que será o produto mais básico de toda a cadeia.
  60. function produzMateriaPrima() public {
  61. // Cria o produto novo;
  62. Produto novoProduto = new Produto("Ferro", "materia prima", endereco);
  63. // Adiciona ao estoque;
  64. estoque.push(novoProduto);
  65. }
  66.  
  67. }
  68.  
  69. // Conforme a execução do trabalho, acreditou-se que ao invés de transportar diretamente o produto de uma posição "A" para "B" seria mais elegante construir
  70. // um "Pacote". O Pacote contém a informação do destino do produto e, também, os produtos que ele contém.
  71. contract Pacote {
  72.  
  73. address enderecoDestino;
  74. Produto produtoTransportado;
  75.  
  76. // Seu constutor se restringe a definir o endereço destino e o produto que ele está transportando. Atualmente ele só pode transportar um produto, mas aqui
  77. // já fica uma sugestão, para trabalhos posteriores, de utilizar alguma outra forma de armazenamento para transporte, seja ele array, uma lista, etc.
  78. constructor(address _enderecoDestino, Produto _produtoTransportado) public{
  79.  
  80. enderecoDestino = _enderecoDestino;
  81. produtoTransportado = _produtoTransportado;
  82. }
  83.  
  84. // Função para obter o endereço destino
  85. function getEnderecoDestino()public view returns (address){
  86. return enderecoDestino;
  87. }
  88.  
  89. // Função para obter o produto do pacote. Aqui seria interessante "destruir" o pacote após a utilização deste método, visto que o motivo do pacote é
  90. // o de fornecer o produto ao seu destinatário;
  91. function getProduto() public view returns (Produto){
  92. return produtoTransportado;
  93. }
  94.  
  95. }
  96.  
  97. //O armazem é outra "Empresa" importante para o rastreamento e, também, exerce as funções básicas de "Estoque". O planejamento pede que no Armazém
  98. // seja salvo o momento em que o produto chega e que o produto sai. Para um trabalho mais elaborado, seria interessante utilizar identificadores
  99. // mais precisos para referenciar qual produto que chegou em cada momento. Mas, nesse primeiro estagio do projeto, vamos só armazenar o tempo de entrada
  100. // e de saída do ultimo produto.
  101. contract Armazem is Empresa, Estoque{
  102.  
  103. //Seu construtor se restringe a definir os seus atributos herdados de "Empresa"
  104. constructor(string _nome) public {
  105. nome = _nome;
  106. endereco = msg.sender;
  107. }
  108.  
  109. //A maioria das implementações de recebe será dessa forma, com exceção do "Manufaturador".
  110. function recebe(Produto _produtoRecebido) public{
  111. estoque.push(_produtoRecebido);
  112. // Quando o produto é recebido e adicionado ao estoque, é o momento de atualizar o seu proprietario
  113. _produtoRecebido.setProprietario(endereco);
  114. }
  115.  
  116. }
  117.  
  118. // Aqui é um exemplo de má implementação do código e ele deveria ser revisado. O objetivo desse contrato era de criar duas instâncias, uma para produzir apenas
  119. // "Dobradiças" a partir de "Ferro" e outra, para para produzir "Portas retráteis" a partir de "Dobradiças" e de mais "Ferro" No final das contas,
  120. // foi criado apenas um Manufaturador que produz as duas coisas, desde que ele possua em seu estoque de produção as devidas quantidades para produção.
  121. // Todos os produtos produzidos pelo Manufaturador são encaminhados para o estoque, mantendo a lógica do contrato "Estoque" e impedindo que ele produza
  122. // o próprio insumo. Ele possuí uma lógica diferente no método "recebe" pois ele precis identificar o tipo do produto que chega antes de alocar;
  123. contract Manufaturador is Empresa, Estoque{
  124. //Este estoque é para consumo próprio durante a produção
  125. Produto[] estoqueDeDobradica;
  126. Produto[] estoqueDeFerro;
  127.  
  128. // Manufaturador é uma "Empresa" no qual é relevante para a rastreabilidade.
  129. constructor(string _nome) public {
  130. nome = _nome;
  131. endereco = msg.sender;
  132. }
  133.  
  134. // Ele implementa diferente o método "recebe" do estoque, pois, como ele é um dos utilizadores de produtos, ele deve alocar o local devido para o produto em suas própria cadeia de
  135. // produção. No exemplo, ele aloca "Ferro" no estoqueDeFerro e aloca o resto no estoqueDeDobradica;
  136. function recebe(Produto _produtoRecebido) public{
  137. if(compareStrings(_produtoRecebido.getTipoProduto(), "materia prima")){
  138. estoqueDeFerro.push(_produtoRecebido);
  139. }else {
  140. estoqueDeDobradica.push(_produtoRecebido);
  141. }
  142. // Quando o produto é recebido e adicionado ao estoque, é o momento de atualizar o seu proprietario
  143. _produtoRecebido.setProprietario(endereco);
  144. }
  145.  
  146. // Não foi encontrado métodos nativos para comparação de strings, sendo assim, foi criado o seguinte método para isso.
  147. function compareStrings (string a, string b)private pure returns (bool){
  148. return keccak256(a) == keccak256(b);
  149. }
  150.  
  151. // Para produzir dobradica se usa a matéria prima "Ferro". Utiliza-se somente uma unidade para o exemplo. Para a produção do novo produto ( a dobradica), é necessário resgatar o valor atual
  152. // da cadeia de forma a manter a integridade dela.
  153. function produzDobradica() public {
  154. // Aqui é resgatado a cadeiaAtual do ferro para, depois ser adicionado à cadeia do produto novo, a dobradica;
  155. address[] memory cadeiaAtual = estoqueDeFerro[estoqueDeFerro.length-1].getCadeia();
  156. // Tratamento do array do estoque de consumo para produção
  157. delete estoqueDeFerro[estoqueDeFerro.length-1];
  158. estoqueDeFerro.length--;
  159. Produto novoProduto = new Produto("Dobradica", "insumo", endereco);
  160. // Agora, depois da confirmação da criação do novo produto, é onde adicionamos o valor anterior da cadeia para o produto novo;
  161. // Temos um problema especial aqui, visto que ao produzir um novo produto adicionamos o proprietario atual como o próprio produtor
  162. // E, ao utilizar um produto de estoque de consumo, estaremos duplicando o proprietario atual.
  163. novoProduto.setCadeia(cadeiaAtual);
  164. estoque.push(novoProduto);
  165. }
  166.  
  167. function teste() public {
  168. estoque[estoque.length-1].getCadeia();
  169. estoque[estoque.length-1].getTipoProduto();
  170. }
  171.  
  172. // Para produzir porta retratil, utiliza-se a matéria prima "Ferro" e "Dobradica". Para tal fim, utiliza-se somente uma unidade de cada uma.
  173. function produzPortaRetratil() public {
  174. // Aqui é resgatado a cadeiaAtual do ferro para, depois ser adicionado à cadeia do produto novo, a porta retratil;
  175. address[] memory cadeiaAtual1 = estoqueDeFerro[estoqueDeFerro.length-1].getCadeia();
  176. // Aqui é resgatado a cadeiaAtual da dobradica para, depois ser adicionado à cadeia do produto novo, a porta retratil;
  177. address[] memory cadeiaAtual2 = estoqueDeDobradica[estoqueDeDobradica.length-1].getCadeia();
  178. // Tratamento do array do estoque de consumo para produção
  179. delete estoqueDeFerro[estoqueDeFerro.length-1];
  180. estoqueDeFerro.length--;
  181. // Tratamento do array do estoque de consumo para produção
  182. delete estoqueDeDobradica[estoqueDeDobradica.length-1];
  183. estoqueDeDobradica.length--;
  184. Produto novoProduto = new Produto("Porta retratil", "insumo", endereco);
  185. //Agora, depois da confirmação da criação do novo produto, é onde adicionamos o valor anterior das cadeia para ao produto novo( a porta retrátil);
  186. novoProduto.setCadeia(cadeiaAtual1);
  187. novoProduto.setCadeia(cadeiaAtual2);
  188. estoque.push(novoProduto);
  189. }
  190.  
  191. }
  192.  
  193. //A Transportadora é outra "Empresa" importante para o rastreamento, contudo, diferente dos outros participantes, ela não é um Estoque, ela somente é responsável pelo transporte de "A" para "B"
  194. contract Transportadora is Empresa{
  195.  
  196. constructor(string _nome) public {
  197. nome = _nome;
  198. endereco = msg.sender;
  199. }
  200. // Entrega para o destino
  201. function entrega(Pacote pacoteParaEntrega) public{
  202. address enderecoDestino = pacoteParaEntrega.getEnderecoDestino();
  203. // Define o transportador como proprietario atual do produto
  204. pacoteParaEntrega.getProduto().setProprietario(endereco);
  205. Estoque(enderecoDestino).recebe(pacoteParaEntrega.getProduto());
  206. }
  207. }
  208.  
  209. contract Produto {
  210.  
  211. // Nome do produto
  212. string nome;
  213. // O tipoDoProduto é para o manufaturador identificar aonde alocar o produto, por enquanto só é relevante se ele é matéria prima ou não.
  214. string tipoProduto;
  215. // O proprietario atual do produto;
  216. address proprietario;
  217. // O produtor se refere a quem produziu ele;
  218. address produtor;
  219. // Array de tadas as empresas que tocaram no produto
  220. address[] cadeia;
  221.  
  222. // Construtor se restringe a definir o nome do produto, o seu tipo, quem é o seu produtor. Se torna implícito que, durante a criação, o proprietario
  223. // seja o proprio produtor.
  224. constructor(string _nome, string _tipoProduto, address _produtorOrigem) public{
  225.  
  226. nome = _nome;
  227. tipoProduto = _tipoProduto;
  228. produtor = _produtorOrigem;
  229. setProprietario(_produtorOrigem);
  230. }
  231.  
  232.  
  233. // Essa funcao deve ser chamada toda vez que o produto mudar de proprietario, seja no momento da produção, durante transporte ou no recebimento
  234. function setProprietario(address _novoProprietario) public{
  235. proprietario = _novoProprietario;
  236. cadeia.push(proprietario);
  237. }
  238.  
  239. // Retorna o tipo do produto
  240. function getTipoProduto() public view returns(string){
  241. return tipoProduto;
  242. }
  243.  
  244. // Retorna a cadeia inteira atual
  245. function getCadeia() public constant returns(address[]){
  246. return cadeia;
  247. }
  248.  
  249. // Adiciona no final do array da cadeia os valores extras de membros da cadeia. Isso deve ser chamado toda vez que o produto for utilizado para criar
  250. // um novo produto. Lembrando que é impossível remover os membros da cadeia depois de terem sido adicionados. O problem atual dessa implementação
  251. // é o de não conseguir armazenar de forma cronológica as empresas e uma duplicação do código de rastreamento ao utilizar um produto como matéria prima.
  252. function setCadeia(address[] cadeiaAtual) public returns(address[]){
  253. for( uint i = 0; i<cadeiaAtual.length-1;i++){
  254. cadeia.push(cadeiaAtual[i]);
  255. }
  256. }
  257.  
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement