Advertisement
Guest User

Untitled

a guest
Jun 19th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.06 KB | None | 0 0
  1. pragma solidity ^0.4.6;
  2. pragma experimental ABIEncoderV2;
  3.  
  4. //Para este trabalho, os atores "Manufaturador", "Transportador", "Armazem" e "Produtor" são considerados entidades importantes para refererência ao rastrear
  5. // a cadeia. Por este motivo, foi criado este contrato genérico no qual será herdado por todas esses contratos, que serão empresas;
  6. contract Empresa{
  7. //O nome da empresa;
  8. string nome;
  9. // O Endereco se refere a "Account" neste caso;
  10. address endereco;
  11.  
  12. // 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
  13. // explicitamente a função dentro das outras que herdam esse contrato. Não foi possível solucionar o problema durante o tempo do trabalho.
  14. function recebe(Produto _produtoRecebido) public{
  15. }
  16.  
  17. //Retorna o nome da empresa
  18. function getNome() public view returns(string){
  19. return nome;
  20. }
  21.  
  22. }
  23.  
  24. // 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
  25. // "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
  26. // 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
  27. // de armazenar e encaminhar produtos para uma outra empresa;
  28. contract Estoque{
  29.  
  30. // Esta variável, estoque, será responsavel por identificar os produtos que serão encaminhados para uma unidade posterior;
  31. Produto[] estoque;
  32. // Esta variável sera o identificador da "Account" do destino do produto;
  33. Empresa destinoProduto;
  34.  
  35. // Essa função tem como objetivo atualizar/definir o destino atual do conteúdo em estoque.
  36. function setDestino(Empresa _enderecoArmazem) public {
  37. destinoProduto = _enderecoArmazem;
  38. }
  39.  
  40. // Essa função utiliza a "Account" de algum transportador no qual será responsável pelo transporte;
  41. function encaminha(Transportadora transportadorResponsavel) public{
  42. // O "Pacote" será explicado posteriormente. Ele é só um contrato onde possuí um produto e um destino, assim o transportador
  43. // pode transportar para outro transportador sem problemas. Para criar o pacote, utiliza-se o produto no topo do array de produtos
  44. // e o destino do produto;
  45. Pacote pacoteParaEntrega= new Pacote(destinoProduto, estoque[estoque.length-1]);
  46. // Tratamento do array de produtos;
  47. delete estoque[estoque.length-1];
  48. estoque.length--;
  49. // Encaminha o pacote para o transportador realizar a entrega;
  50. transportadorResponsavel.entrega(pacoteParaEntrega);
  51. }
  52.  
  53. }
  54.  
  55. // 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
  56. // "produtos" a partir do "nada"
  57. contract Produtor is Empresa, Estoque{
  58.  
  59. // Seu construtor se restringe a definir os seus atributos herdados de "Empresa", visto que o Produtor é uma empresa relevante para o rastreamento.
  60. constructor(string _nome) public {
  61. nome = _nome;
  62. endereco = msg.sender;
  63. }
  64.  
  65. // Este método simplesmente produz o "Produto" matéria prima, que será o produto mais básico de toda a cadeia.
  66. function produzMateriaPrima() public {
  67. // Cria o produto novo;
  68. Produto novoProduto = new Produto("Ferro", "materia prima", this);
  69. // Adiciona ao estoque;
  70. estoque.push(novoProduto);
  71. }
  72.  
  73. }
  74.  
  75. // 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
  76. // um "Pacote". O Pacote contém a informação do destino do produto e, também, os produtos que ele contém.
  77. contract Pacote {
  78.  
  79. Empresa enderecoDestino;
  80. Produto produtoTransportado;
  81.  
  82. // 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
  83. // já fica uma sugestão, para trabalhos posteriores, de utilizar alguma outra forma de armazenamento para transporte, seja ele array, uma lista, etc.
  84. constructor(Empresa _enderecoDestino, Produto _produtoTransportado) public{
  85.  
  86. enderecoDestino = _enderecoDestino;
  87. produtoTransportado = _produtoTransportado;
  88. }
  89.  
  90. // Função para obter o endereço destino
  91. function getEnderecoDestino()public view returns (Empresa){
  92. return enderecoDestino;
  93. }
  94.  
  95. // 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 é
  96. // o de fornecer o produto ao seu destinatário;
  97. function getProduto() public view returns (Produto){
  98. return produtoTransportado;
  99. }
  100.  
  101. }
  102.  
  103. //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
  104. // seja salvo o momento em que o produto chega e que o produto sai. Para um trabalho mais elaborado, seria interessante utilizar identificadores
  105. // mais precisos para referenciar qual produto que chegou em cada momento. Mas, nesse primeiro estagio do projeto, vamos só armazenar o tempo de entrada
  106. // e de saída do ultimo produto.
  107. contract Armazem is Empresa, Estoque{
  108.  
  109. uint tempoChegada;
  110. uint tempoSaida;
  111.  
  112. //Seu construtor se restringe a definir os seus atributos herdados de "Empresa"
  113. constructor(string _nome) public {
  114. nome = _nome;
  115. endereco = msg.sender;
  116. }
  117.  
  118. //A maioria das implementações de recebe será dessa forma, com exceção do "Manufaturador".
  119. function recebe(Produto _produtoRecebido) public{
  120. tempoChegada = now;
  121. estoque.push(_produtoRecebido);
  122. // Quando o produto é recebido e adicionado ao estoque, é o momento de atualizar o seu proprietario
  123. _produtoRecebido.setProprietario(this);
  124. }
  125.  
  126. //Unica diferença do método do Estoque é o de atualizar o tempo de saída.
  127. function encaminha(Transportadora transportadorResponsavel) public{
  128. tempoSaida = now;
  129. // O "Pacote" será explicado posteriormente. Ele é só um contrato onde possuí um produto e um destino, assim o transportador
  130. // pode transportar para outro transportador sem problemas. Para criar o pacote, utiliza-se o produto no topo do array de produtos
  131. // e o destino do produto;
  132. Pacote pacoteParaEntrega= new Pacote(destinoProduto, estoque[estoque.length-1]);
  133. // Tratamento do array de produtos;
  134. delete estoque[estoque.length-1];
  135. estoque.length--;
  136. // Encaminha o pacote para o transportador realizar a entrega;
  137. transportadorResponsavel.entrega(pacoteParaEntrega);
  138. }
  139.  
  140. }
  141.  
  142. // 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
  143. // "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,
  144. // 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.
  145. // Todos os produtos produzidos pelo Manufaturador são encaminhados para o estoque, mantendo a lógica do contrato "Estoque" e impedindo que ele produza
  146. // 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;
  147. contract Manufaturador is Empresa, Estoque{
  148. //Este estoque é para consumo próprio durante a produção
  149. Produto[] estoqueDeDobradica;
  150. Produto[] estoqueDeFerro;
  151.  
  152. // Manufaturador é uma "Empresa" no qual é relevante para a rastreabilidade.
  153. constructor(string _nome) public {
  154. nome = _nome;
  155. endereco = msg.sender;
  156. }
  157.  
  158. // 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
  159. // produção. No exemplo, ele aloca "Ferro" no estoqueDeFerro e aloca o resto no estoqueDeDobradica;
  160. function recebe(Produto _produtoRecebido) public{
  161. if(compareStrings(_produtoRecebido.getTipoProduto(), "materia prima")){
  162. estoqueDeFerro.push(_produtoRecebido);
  163. }else {
  164. estoqueDeDobradica.push(_produtoRecebido);
  165. }
  166. // Quando o produto é recebido e adicionado ao estoque, é o momento de atualizar o seu proprietario
  167. _produtoRecebido.setProprietario(this);
  168. }
  169.  
  170. // Não foi encontrado métodos nativos para comparação de strings, sendo assim, foi criado o seguinte método para isso.
  171. function compareStrings (string a, string b)private pure returns (bool){
  172. return keccak256(a) == keccak256(b);
  173. }
  174.  
  175. // 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
  176. // da cadeia de forma a manter a integridade dela.
  177. function produzDobradica() public {
  178. // Aqui é resgatado a cadeiaAtual do ferro para, depois ser adicionado à cadeia do produto novo, a dobradica;
  179. Empresa[] memory cadeiaAtual = estoqueDeFerro[estoqueDeFerro.length-1].getCadeia();
  180. // Tratamento do array do estoque de consumo para produção
  181. delete estoqueDeFerro[estoqueDeFerro.length-1];
  182. estoqueDeFerro.length--;
  183. Produto novoProduto = new Produto("Dobradica", "insumo", this);
  184. // Agora, depois da confirmação da criação do novo produto, é onde adicionamos o valor anterior da cadeia para o produto novo;
  185. // Temos um problema especial aqui, visto que ao produzir um novo produto adicionamos o proprietario atual como o próprio produtor
  186. // E, ao utilizar um produto de estoque de consumo, estaremos duplicando o proprietario atual.
  187. novoProduto.setCadeia(cadeiaAtual);
  188. estoque.push(novoProduto);
  189. }
  190.  
  191. // Para produzir porta retratil, utiliza-se a matéria prima "Ferro" e "Dobradica". Para tal fim, utiliza-se somente uma unidade de cada uma.
  192. function produzPortaRetratil() public {
  193. // Aqui é resgatado a cadeiaAtual do ferro para, depois ser adicionado à cadeia do produto novo, a porta retratil;
  194. Empresa[] memory cadeiaAtual1 = estoqueDeFerro[estoqueDeFerro.length-1].getCadeia();
  195. // Aqui é resgatado a cadeiaAtual da dobradica para, depois ser adicionado à cadeia do produto novo, a porta retratil;
  196. Empresa[] memory cadeiaAtual2 = estoqueDeDobradica[estoqueDeDobradica.length-1].getCadeia();
  197. // Tratamento do array do estoque de consumo para produção
  198. //delete estoqueDeFerro[estoqueDeFerro.length-1];
  199. estoqueDeFerro.length--;
  200. // Tratamento do array do estoque de consumo para produção
  201. //delete estoqueDeDobradica[estoqueDeDobradica.length-1];
  202. estoqueDeDobradica.length--;
  203. Produto novoProduto = new Produto("Porta retratil", "insumo", this);
  204. //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);
  205. novoProduto.setCadeia(cadeiaAtual1);
  206. novoProduto.setCadeia(cadeiaAtual2);
  207. estoque.push(novoProduto);
  208. }
  209.  
  210. }
  211.  
  212. //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"
  213. contract Transportadora is Empresa{
  214.  
  215. constructor(string _nome) public {
  216. nome = _nome;
  217. endereco = msg.sender;
  218. }
  219. // Entrega para o destino
  220. function entrega(Pacote pacoteParaEntrega) public{
  221. Empresa enderecoDestino = pacoteParaEntrega.getEnderecoDestino();
  222. // Define o transportador como proprietario atual do produto
  223. pacoteParaEntrega.getProduto().setProprietario(this);
  224. Empresa(enderecoDestino).recebe(pacoteParaEntrega.getProduto());
  225. }
  226. }
  227.  
  228. contract Produto {
  229.  
  230. // Nome do produto
  231. string nome;
  232. // O tipoDoProduto é para o manufaturador identificar aonde alocar o produto, por enquanto só é relevante se ele é matéria prima ou não.
  233. string tipoProduto;
  234. // O proprietario atual do produto;
  235. Empresa proprietario;
  236. // O produtor se refere a quem produziu ele;
  237. Empresa produtor;
  238. // Array de tadas as empresas que tocaram no produto
  239. Empresa[] cadeia;
  240.  
  241. // 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
  242. // seja o proprio produtor.
  243. constructor(string _nome, string _tipoProduto, Empresa _produtorOrigem) public{
  244.  
  245. nome = _nome;
  246. tipoProduto = _tipoProduto;
  247. produtor = _produtorOrigem;
  248. setProprietario(_produtorOrigem);
  249. }
  250.  
  251.  
  252. // Essa funcao deve ser chamada toda vez que o produto mudar de proprietario, seja no momento da produção, durante transporte ou no recebimento
  253. function setProprietario(Empresa _novoProprietario) public{
  254. proprietario = _novoProprietario;
  255. cadeia.push(proprietario);
  256. }
  257.  
  258. // Retorna o tipo do produto
  259. function getTipoProduto() public view returns(string){
  260. return tipoProduto;
  261. }
  262.  
  263. // Retorna a cadeia inteira atual
  264. function getCadeia() public constant returns(Empresa[]){
  265. return cadeia;
  266. }
  267.  
  268.  
  269. // Essa funcao nunca foi realmente validada por sempre acusar "falta de combustível". Não sei se ela realmente funciona ou não.
  270. function getNomeCadeia() public constant returns(string[]){
  271. string[] nomesDaCadeia;
  272. for( uint i = 0; i<cadeia.length-1;i++){
  273. nomesDaCadeia[0] = cadeia[0].getNome();
  274. }
  275. return nomesDaCadeia;
  276. }
  277.  
  278. function getNome() public constant returns(string){
  279. return nome;
  280. }
  281.  
  282. // 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
  283. // um novo produto. Lembrando que é impossível remover os membros da cadeia depois de terem sido adicionados. O problem atual dessa implementação
  284. // é 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.
  285. function setCadeia(Empresa[] cadeiaAtual) public{
  286. for( uint i = 0; i<cadeiaAtual.length-1;i++){
  287. cadeia.push(cadeiaAtual[i]);
  288. }
  289. }
  290.  
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement